1 /-
2 Copyright (c) 2014 Parikshit Khanna. All rights reserved.
3 Released under Apache 2.0 license as described in the file LICENSE.
4 Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
5
6 Basic properties of lists.
7 -/
8 import
9 tactic.interactive tactic.mk_iff_of_inductive_prop
src └────────────────┘ └─────────────────────────────┘
10 logic.basic logic.function logic.relator
src └─────────┘ └────────────┘ └───────────┘
11 algebra.group order.basic
src └───────────┘ └─────────┘
12 data.list.defs data.nat.basic data.option.basic
src └────────────┘ └────────────┘ └───────────────┘
13 data.bool data.prod data.fin
src └───────┘ └───────┘ └──────┘
14 open function nat
15
16 namespace list
17 universes u v w x
18 variables {α : Type u} {β : Type v} {γ : Type w} {δ : Type x}
19
20 instance : is_left_id (list α) has_append.append [] :=
id └────────┘ └──┘ ┴ └───────────────┘ └┘
src └────────┘ └──┘ └───────────────┘ └┘
typ └────────┘ └──┘ ┴ └───────────────┘ └┘
21 ⟨ nil_append ⟩
id └────────┘
src └────────┘
typ └────────┘
22
23 instance : is_right_id (list α) has_append.append [] :=
id └─────────┘ └──┘ ┴ └───────────────┘ └┘
src └─────────┘ └──┘ └───────────────┘ └┘
typ └─────────┘ └──┘ ┴ └───────────────┘ └┘
24 ⟨ append_nil ⟩
id └────────┘
src └────────┘
typ └────────┘
25
26 instance : is_associative (list α) has_append.append :=
id └────────────┘ └──┘ ┴ └───────────────┘
src └────────────┘ └──┘ └───────────────┘
typ └────────────┘ └──┘ ┴ └───────────────┘
27 ⟨ append_assoc ⟩
id └──────────┘
src └──────────┘
typ └──────────┘
28
29 @[simp] theorem cons_ne_nil (a : α) (l : list α) : a::l ≠ [].
id ┴ └──┘ ┴ ┴└┘┴ ┴ └┘
src └──┘ └┘ ┴ └┘
typ ┴ └──┘ ┴ ┴└┘┴ ┴ └┘
doc └──┘
30
31 theorem head_eq_of_cons_eq {h₁ h₂ : α} {t₁ t₂ : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
32 (h₁::t₁) = (h₂::t₂) → h₁ = h₂ :=
id └┘└┘└┘ ┴ └┘└┘└┘ └┘ ┴ └┘
src └┘ ┴ └┘ ┴
typ └┘└┘└┘ ┴ └┘└┘└┘ └┘ ┴ └┘
33 assume Peq, list.no_confusion Peq (assume Pheq Pteq, Pheq)
id └─┘ └───────────────┘ └─┘ └──┘ └──┘ └──┘
src └───────────────┘
typ └─┘ └───────────────┘ └─┘ └──┘ └──┘ └──┘
34
35 theorem tail_eq_of_cons_eq {h₁ h₂ : α} {t₁ t₂ : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
36 (h₁::t₁) = (h₂::t₂) → t₁ = t₂ :=
id └┘└┘└┘ ┴ └┘└┘└┘ └┘ ┴ └┘
src └┘ ┴ └┘ ┴
typ └┘└┘└┘ ┴ └┘└┘└┘ └┘ ┴ └┘
37 assume Peq, list.no_confusion Peq (assume Pheq Pteq, Pteq)
id └─┘ └───────────────┘ └─┘ └──┘ └──┘ └──┘
src └───────────────┘
typ └─┘ └───────────────┘ └─┘ └──┘ └──┘ └──┘
38
39 theorem cons_inj {a : α} : injective (cons a) :=
id ┴ └───────┘ └──┘ ┴
src └───────┘ └──┘
typ ┴ └───────┘ └──┘ ┴
40 assume l₁ l₂, assume Pe, tail_eq_of_cons_eq Pe
id └┘ └┘ └┘ └────────────────┘ └┘
src └────────────────┘
typ └┘ └┘ └┘ └────────────────┘ └┘
41
42 @[simp] theorem cons_inj' (a : α) {l l' : list α} : a::l = a::l' ↔ l = l' :=
id ┴ └──┘ ┴ ┴└┘┴ ┴ ┴└┘└┘ ┴ ┴ ┴ └┘
src └──┘ └┘ ┴ └┘ ┴ ┴
typ ┴ └──┘ ┴ ┴└┘┴ ┴ ┴└┘└┘ ┴ ┴ ┴ └┘
doc └──┘
43 ⟨λ e, cons_inj e, congr_arg _⟩
id ┴ └──────┘ ┴ └───────┘
src └──────┘ └───────┘
typ ┴ └──────┘ ┴ └───────┘
44
45 /- mem -/
46
47 theorem mem_singleton_self (a : α) : a ∈ [a] := mem_cons_self _ _
id ┴ ┴ ┴ ┴┴┴ └───────────┘
src ┴ ┴ ┴ └───────────┘
typ ┴ ┴ ┴ ┴┴┴ └───────────┘
48
49 theorem eq_of_mem_singleton {a b : α} : a ∈ [b] → a = b :=
id ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴
src ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴
50 assume : a ∈ [b], or.elim (eq_or_mem_of_mem_cons this)
id ┴ ┴ ┴┴┴ └─────┘ └───────────────────┘ └──┘
src ┴ ┴ ┴ └─────┘ └───────────────────┘
typ ┴ ┴ ┴┴┴ └─────┘ └───────────────────┘ └──┘
51 (assume : a = b, this)
id ┴ ┴ ┴ └──┘
src ┴
typ ┴ ┴ ┴ └──┘
52 (assume : a ∈ [], absurd this (not_mem_nil a))
id ┴ ┴ └┘ └────┘ └──┘ └─────────┘ ┴
src ┴ └┘ └────┘ └─────────┘
typ ┴ ┴ └┘ └────┘ └──┘ └─────────┘ ┴
53
54 @[simp] theorem mem_singleton {a b : α} : a ∈ [b] ↔ a = b :=
id ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴
doc └──┘
55 ⟨eq_of_mem_singleton, or.inl⟩
id └─────────────────┘ └────┘
src └─────────────────┘ └────┘
typ └─────────────────┘ └────┘
56
57 theorem mem_of_mem_cons_of_mem {a b : α} {l : list α} : a ∈ b::l → b ∈ l → a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ ┴
58 assume ainbl binl, or.elim (eq_or_mem_of_mem_cons ainbl)
id └───┘ └──┘ └─────┘ └───────────────────┘ └───┘
src └─────┘ └───────────────────┘
typ └───┘ └──┘ └─────┘ └───────────────────┘ └───┘
59 (assume : a = b, begin subst a, exact binl end)
id ┴ ┴ ┴ ┴ └──┘
src ┴ └────┘ └────┘ ┴
typ ┴ ┴ ┴ └────┘┴ └────┘└──┘┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st └───────────┘└───────────┘└─┘
60 (assume : a ∈ l, this)
id ┴ ┴ ┴ └──┘
src ┴
typ ┴ ┴ ┴ └──┘
61
62 theorem eq_or_ne_mem_of_mem {a b : α} {l : list α} (h : a ∈ b :: l) : a = b ∨ (a ≠ b ∧ a ∈ l) :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └┘ ┴ ┴ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
63 classical.by_cases or.inl $ assume : a ≠ b, h.elim or.inl $ assume h, or.inr ⟨this, h⟩
id └────────────────┘ └────┘ ┴ ┴ ┴ ┴└───┘ └────┘ ┴ └────┘ └──┘ ┴
src └────────────────┘ └────┘ ┴ └───┘ └────┘ └────┘
typ └────────────────┘ └────┘ ┴ ┴ ┴ ┴└───┘ └────┘ ┴ └────┘ └──┘ ┴
64
65 theorem not_mem_append {a : α} {s t : list α} (h₁ : a ∉ s) (h₂ : a ∉ t) : a ∉ s ++ t :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴
src └──┘ ┴ ┴ ┴ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴
66 mt mem_append.1 $ not_or_distrib.2 ⟨h₁, h₂⟩
id └┘ └────────┘┴ └────────────┘┴ └┘ └┘
src └┘ └────────┘┴ └────────────┘┴
typ └┘ └────────┘┴ └────────────┘┴ └┘ └┘
67
68 theorem ne_nil_of_mem {a : α} {l : list α} (h : a ∈ l) : l ≠ [] :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘
src └──┘ ┴ ┴ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘
69 by intro e; rw e at h; cases h
id ┴ ┴
src └─────┘ └─┘ └───┘ └────┘ └
typ └─────┘ └─┘┴└───┘ └────┘┴└
doc └─────┘ └─┘ └───┘ └────┘ └
txt └─────┘ └─┘ └───┘ └────┘ └
par └─────┘ └─┘ └───┘ └────┘ └
pid └┘ ┴ └───┘ ┴ └
st └───────────┘┴└──────────────
70
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
71 theorem mem_split {a : α} {l : list α} (h : a ∈ l) : ∃ s t : list α, l = s ++ a :: t :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴
src └──┘ ┴ ┴ └──┘ ┴ ┴ └┘ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴
72 begin
st └─────
73 induction l with b l ih, {cases h}, rcases h with rfl | h,
id ┴ ┴ ┴
src └────────┘ └──────────┘ └────┘ └─────┘ └───────────┘
typ └────────┘┴└──────────┘ └────┘┴ └─────┘┴└───────────┘
doc └────────┘ └──────────┘ └────┘ └─────┘ └───────────┘
txt └────────┘ └──────────┘ └────┘ └─────┘ └───────────┘
par └────────┘ └──────────┘ └────┘ └─────┘ └───────────┘
pid ┴ ┴└─────────┘ ┴ ┴ └───────────┘
st ────────────────────────┘└────────┘└┘└────────────────────┘└─
74 { exact ⟨[], l, rfl⟩ },
id ┴ └─┘
src └────┘ └┘ └┘└─┘└┘
typ └────┘ └┘┴└┘└─┘└┘
doc └────┘ └┘ └┘ └┘
txt └────┘ └┘ └┘ └┘
par └────┘ └┘ └┘ └┘
pid ┴ └┘ └┘ ┴┴
st ───┘└─────────────────┘└┘└
75 { rcases ih h with ⟨s, t, rfl⟩,
id └┘ ┴
src └─────┘ ┴ └───────────────┘
typ └─────┘└┘┴┴└───────────────┘
doc └─────┘ ┴ └───────────────┘
txt └─────┘ ┴ └───────────────┘
par └─────┘ ┴ └───────────────┘
pid ┴ ┴ └───────────────┘
st ───────────────────────────────┘└─
76 exact ⟨b::s, t, rfl⟩ }
id ┴ ┴ ┴ └─┘
src └────┘ └┘ └┘└─┘└┘
typ └────┘ ┴ ┴└┘┴└┘└─┘└┘
doc └────┘ └┘ └┘ └┘
txt └────┘ └┘ └┘ └┘
par └────┘ └┘ └┘ └┘
pid ┴ └┘ └┘ ┴┴
st ────────────────────────┘└─
77 end
st ──┘
78
79 theorem mem_of_ne_of_mem {a y : α} {l : list α} (h₁ : a ≠ y) (h₂ : a ∈ y :: l) : a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ └┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴
80 or.elim (eq_or_mem_of_mem_cons h₂) (λe, absurd e h₁) (λr, r)
id └─────┘ └───────────────────┘ └┘ ┴ └────┘ ┴ └┘ ┴ ┴
src └─────┘ └───────────────────┘ └────┘
typ └─────┘ └───────────────────┘ └┘ ┴ └────┘ ┴ └┘ ┴ ┴
81
82 theorem ne_of_not_mem_cons {a b : α} {l : list α} : a ∉ b::l → a ≠ b :=
id ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴
src └──┘ ┴ └┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴
83 assume nin aeqb, absurd (or.inl aeqb) nin
id └─┘ └──┘ └────┘ └────┘ └──┘ └─┘
src └────┘ └────┘
typ └─┘ └──┘ └────┘ └────┘ └──┘ └─┘
84
85 theorem not_mem_of_not_mem_cons {a b : α} {l : list α} : a ∉ b::l → a ∉ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴
src └──┘ ┴ └┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴
86 assume nin nainl, absurd (or.inr nainl) nin
id └─┘ └───┘ └────┘ └────┘ └───┘ └─┘
src └────┘ └────┘
typ └─┘ └───┘ └────┘ └────┘ └───┘ └─┘
87
88 theorem not_mem_cons_of_ne_of_not_mem {a y : α} {l : list α} : a ≠ y → a ∉ l → a ∉ y::l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴└┘┴
src └──┘ ┴ ┴ ┴ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴└┘┴
89 assume p1 p2, not.intro (assume Pain, absurd (eq_or_mem_of_mem_cons Pain) (not_or p1 p2))
id └┘ └┘ └───────┘ └──┘ └────┘ └───────────────────┘ └──┘ └────┘ └┘ └┘
src └───────┘ └────┘ └───────────────────┘ └────┘
typ └┘ └┘ └───────┘ └──┘ └────┘ └───────────────────┘ └──┘ └────┘ └┘ └┘
90
91 theorem ne_and_not_mem_of_not_mem_cons {a y : α} {l : list α} : a ∉ y::l → a ≠ y ∧ a ∉ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
92 assume p, and.intro (ne_of_not_mem_cons p) (not_mem_of_not_mem_cons p)
id ┴ └───────┘ └────────────────┘ ┴ └─────────────────────┘ ┴
src └───────┘ └────────────────┘ └─────────────────────┘
typ ┴ └───────┘ └────────────────┘ ┴ └─────────────────────┘ ┴
93
94 theorem mem_map_of_mem (f : α → β) {a : α} {l : list α} (h : a ∈ l) : f a ∈ map f l :=
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ ┴ ┴ └─┘
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
95 begin
st └─────
96 induction l with b l' ih,
id ┴
src └────────┘ └───────────┘
typ └────────┘┴└───────────┘
doc └────────┘ └───────────┘
txt └────────┘ └───────────┘
par └────────┘ └───────────┘
pid ┴ ┴└──────────┘
st ─────────────────────────┘└─
97 {cases h},
id ┴
src └────┘
typ └────┘┴
doc └────┘
txt └────┘
par └────┘
pid ┴
st ─────────┘└┘└
98 {rcases h with rfl | h,
id ┴
src └─────┘ └───────────┘
typ └─────┘┴└───────────┘
doc └─────┘ └───────────┘
txt └─────┘ └───────────┘
par └─────┘ └───────────┘
pid ┴ └───────────┘
st ───────────────────────┘└─
99 {exact or.inl rfl},
id └────┘ └─┘
src └────┘└────┘┴└─┘
typ └────┘└────┘┴└─┘
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ────────────────────┘└┘└
100 {exact or.inr (ih h)}}
id └────┘ └┘ ┴
src └────┘└────┘┴ ┴ ┴
typ └────┘└────┘┴ └┘┴┴┴
doc └────┘ ┴ ┴ ┴
txt └────┘ ┴ ┴ ┴
par └────┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ───────────────────────┘└──
101 end
st ──┘
102
103 theorem exists_of_mem_map {f : α → β} {b : β} {l : list α} (h : b ∈ map f l) : ∃ a, a ∈ l ∧ f a = b :=
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
104 begin
st └─────
105 induction l with c l' ih,
id ┴
src └────────┘ └───────────┘
typ └────────┘┴└───────────┘
doc └────────┘ └───────────┘
txt └────────┘ └───────────┘
par └────────┘ └───────────┘
pid ┴ ┴└──────────┘
st ─────────────────────────┘└─
106 {cases h},
id ┴
src └────┘
typ └────┘┴
doc └────┘
txt └────┘
par └────┘
pid ┴
st ─────────┘└┘└
107 {cases (eq_or_mem_of_mem_cons h) with h h,
id └───────────────────┘ ┴
src └────┘ └───────────────────┘┴ └────────┘
typ └────┘ └───────────────────┘┴┴└────────┘
doc └────┘ ┴ └────────┘
txt └────┘ ┴ └────────┘
par └────┘ ┴ └────────┘
pid ┴ ┴ ┴└───────┘
st ──────────────────────────────────────────┘└─
108 {exact ⟨c, mem_cons_self _ _, h.symm⟩},
id ┴ └───────────┘ └────┘
src └────┘ └┘└───────────┘└────┘└────┘┴
typ └────┘ ┴└┘└───────────┘└────┘└────┘┴
doc └────┘ └┘ └────┘ ┴
txt └────┘ └┘ └────┘ ┴
par └────┘ └┘ └────┘ ┴
pid ┴ └┘ └────┘ ┴
st ────────────────────────────────────────┘└┘└
109 {rcases ih h with ⟨a, ha₁, ha₂⟩,
id └┘ ┴
src └─────┘ ┴ └─────────────────┘
typ └─────┘└┘┴┴└─────────────────┘
doc └─────┘ ┴ └─────────────────┘
txt └─────┘ ┴ └─────────────────┘
par └─────┘ ┴ └─────────────────┘
pid ┴ ┴ └─────────────────┘
st ──────────────────────────────────┘└─
110 exact ⟨a, mem_cons_of_mem _ ha₁, ha₂⟩ }}
id ┴ └─────────────┘ └─┘ └─┘
src └────┘ └┘└─────────────┘└─┘ └┘ └┘
typ └────┘ ┴└┘└─────────────┘└─┘└─┘└┘└─┘└┘
doc └────┘ └┘ └─┘ └┘ └┘
txt └────┘ └┘ └─┘ └┘ └┘
par └────┘ └┘ └─┘ └┘ └┘
pid ┴ └┘ └─┘ └┘ ┴┴
st ───────────────────────────────────────────┘└──
111 end
st ──┘
112
113 @[simp] theorem mem_map {f : α → β} {b : β} {l : list α} : b ∈ map f l ↔ ∃ a, a ∈ l ∧ f a = b :=
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘
114 ⟨exists_of_mem_map, λ ⟨a, la, h⟩, by rw [← h]; exact mem_map_of_mem f la⟩
id └───────────────┘ ┴ ┴ └────────────┘ ┴ └┘
src └───────────────┘ └────┘ ┴ └────┘└────────────┘┴ ┴
typ └───────────────┘ ┴ └────┘┴┴ └────┘└────────────┘┴┴┴└┘
doc └────┘ ┴ └────┘ ┴ ┴
txt └────┘ ┴ └────┘ ┴ ┴
par └────┘ ┴ └────┘ ┴ ┴
pid └──┘ ┴ ┴ ┴ ┴
st └──────┘┴└─────────────────────────┘
115
116 @[simp] theorem mem_map_of_inj {f : α → β} (H : injective f) {a : α} {l : list α} :
id ┴ ┴ └───────┘ ┴ ┴ └──┘ ┴
src └───────┘ └──┘
typ ┴ ┴ └───────┘ ┴ ┴ └──┘ ┴
doc └──┘
117 f a ∈ map f l ↔ a ∈ l :=
id ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └─┘ ┴ ┴
typ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
118 ⟨λ m, let ⟨a', m', e⟩ := exists_of_mem_map m in H e ▸ m', mem_map_of_mem _⟩
id ┴ └─┘ └┘ ┴ └───────────────┘ ┴ ┴ ┴ └────────────┘
src └───────────────┘ ┴ └────────────┘
typ ┴ └─┘ └┘ ┴ └───────────────┘ ┴ ┴ ┴ └────────────┘
119
120 @[simp] lemma map_eq_nil {f : α → β} {l : list α} : list.map f l = [] ↔ l = [] :=
id ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ └──────┘ ┴ └┘ ┴ ┴ └┘
typ ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
121 ⟨by cases l; simp only [forall_prop_of_true, map, forall_prop_of_false, not_false_iff],
id ┴ └─────────────────┘ └─┘ └──────────────────┘ └───────────┘
src └────┘ └─────────┘└─────────────────┘└┘└─┘└┘└──────────────────┘└┘└───────────┘┴
typ └────┘┴ └─────────┘└─────────────────┘└┘└─┘└┘└──────────────────┘└┘└───────────┘┴
doc └────┘ └─────────┘ └┘ └┘ └┘ ┴
txt └────┘ └─────────┘ └┘ └┘ └┘ ┴
par └────┘ └─────────┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──┘└┘ └┘ └┘ └┘ ┴
st └─────────────────────────────────────────────────────────────────────────────────┘
122 λ h, h.symm ▸ rfl⟩
id ┴ ┴└───┘ ┴ └─┘
src └───┘ ┴ └─┘
typ ┴ ┴└───┘ ┴ └─┘
123
124 @[simp] theorem mem_join {a : α} : ∀ {L : list (list α)}, a ∈ join L ↔ ∃ l, l ∈ L ∧ a ∈ l
id ┴ ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘
125 | [] := ⟨false.elim, λ⟨_, h, _⟩, false.elim h⟩
id └┘ └────────┘ ┴ ┴ └────────┘
src └┘ └────────┘ └────────┘
typ └┘ └────────┘ ┴ ┴ └────────┘
126 | (c :: L) := by simp only [join, mem_append, @mem_join L, mem_cons_iff, or_and_distrib_right, exists_or_distrib, exists_eq_left]
id └┘ └──┘ └────────┘ └──────┘ ┴ └──────────┘ └──────────────────┘ └───────────────┘ └────────────┘
src └┘ └─────────┘└──┘└┘└────────┘└┘ ┴ └┘└──────────┘└┘└──────────────────┘└┘└───────────────┘└┘└────────────┘└─
typ └┘ └─────────┘└──┘└┘└────────┘└┘ └──────┘┴┴└┘└──────────┘└┘└──────────────────┘└┘└───────────────┘└┘└────────────┘└─
doc └─────────┘ └┘ └┘ ┴ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ ┴ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ ┴ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴ └┘ └┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────
127
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
128 theorem exists_of_mem_join {a : α} {L : list (list α)} : a ∈ join L → ∃ l, l ∈ L ∧ a ∈ l :=
id ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴
typ ┴ └──┘ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
129 mem_join.1
id └──────┘┴
src └──────┘┴
typ └──────┘┴
130
131 theorem mem_join_of_mem {a : α} {L : list (list α)} {l} (lL : l ∈ L) (al : a ∈ l) : a ∈ join L :=
id ┴ └──┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘ └──┘ ┴ ┴ ┴ └──┘
typ ┴ └──┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
132 mem_join.2 ⟨l, lL, al⟩
id └──────┘┴ ┴ └┘ └┘
src └──────┘┴
typ └──────┘┴ ┴ └┘ └┘
133
134 @[simp] theorem mem_bind {b : β} {l : list α} {f : α → list β} : b ∈ list.bind l f ↔ ∃ a ∈ l, b ∈ f a :=
id ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ └───────┘ ┴ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴
doc └──┘
135 iff.trans mem_join
id └───────┘ └──────┘
src └───────┘ └──────┘
typ └───────┘ └──────┘
136 ⟨λ ⟨l', h1, h2⟩, let ⟨a, al, fa⟩ := exists_of_mem_map h1 in ⟨a, al, fa.symm ▸ h2⟩,
id ┴ └┘ └┘ └─┘ ┴ └┘ └┘ └───────────────┘ └───┘ ┴
src └───────────────┘ └───┘ ┴
typ ┴ └┘ └┘ └─┘ ┴ └┘ └┘ └───────────────┘ └───┘ ┴
137 λ ⟨a, al, bfa⟩, ⟨f a, mem_map_of_mem _ al, bfa⟩⟩
id ┴┴ └┘ └─┘ ┴ └────────────┘
src └────────────┘
typ ┴┴ └┘ └─┘ ┴ └────────────┘
138
139 theorem exists_of_mem_bind {b : β} {l : list α} {f : α → list β} : b ∈ list.bind l f → ∃ a ∈ l, b ∈ f a :=
id ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ └───────┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴
140 mem_bind.1
id └──────┘┴
src └──────┘┴
typ └──────┘┴
141
142 theorem mem_bind_of_mem {b : β} {l : list α} {f : α → list β} {a} (al : a ∈ l) (h : b ∈ f a) : b ∈ list.bind l f :=
id ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴
src └──┘ └──┘ ┴ ┴ ┴ └───────┘
typ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴
143 mem_bind.2 ⟨a, al, h⟩
id └──────┘┴ ┴ └┘ ┴
src └──────┘┴
typ └──────┘┴ ┴ └┘ ┴
144
145 lemma bind_map {g : α → list β} {f : β → γ} :
id ┴ └──┘ ┴ ┴ ┴
src └──┘
typ ┴ └──┘ ┴ ┴ ┴
146 ∀(l : list α), list.map f (l.bind g) = l.bind (λa, (g a).map f)
id ┴ └──┘ ┴ └──────┘ ┴ ┴└───┘ ┴ ┴ ┴└───┘ ┴ ┴ ┴ └─┘ ┴
src └──┘ └──────┘ └───┘ ┴ └───┘ └─┘
typ ┴ └──┘ ┴ └──────┘ ┴ ┴└───┘ ┴ ┴ ┴└───┘ ┴ ┴ ┴ └─┘ ┴
147 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
148 | (a::l) := by simp only [cons_bind, map_append, bind_map l]
id └┘ └───────┘ └────────┘ └──────┘ ┴
src └┘ └─────────┘└───────┘└┘└────────┘└┘ ┴ └─
typ └┘ └─────────┘└───────┘└┘└────────┘└┘└──────┘┴┴└─
doc └─────────┘ └┘ └┘ ┴ └─
txt └─────────┘ └┘ └┘ ┴ └─
par └─────────┘ └┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴└
st └──────────────────────────────────────────────
149
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
150 /- length -/
src ─────────────
typ ─────────────
doc ─────────────
txt ─────────────
par ─────────────
pid ─────────────
st ─────────────
151
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
152 theorem length_eq_zero {l : list α} : length l = 0 ↔ l = [] :=
id └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
src └──┘ └────┘ ┴ ┴ ┴ └┘
typ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
153 ⟨eq_nil_of_length_eq_zero, λ h, h.symm ▸ rfl⟩
id └──────────────────────┘ ┴ ┴└───┘ ┴ └─┘
src └──────────────────────┘ └───┘ ┴ └─┘
typ └──────────────────────┘ ┴ ┴└───┘ ┴ └─┘
154
155 theorem length_pos_of_mem {a : α} : ∀ {l : list α}, a ∈ l → 0 < length l
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴
src └──┘ ┴ ┴ └────┘
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴
156 | (b::l) _ := zero_lt_succ _
id └┘ └──────────┘
src └┘ └──────────┘
typ └┘ └──────────┘
157
158 theorem exists_mem_of_length_pos : ∀ {l : list α}, 0 < length l → ∃ a, a ∈ l
id ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴┴ ┴ ┴ ┴
159 | (b::l) _ := ⟨b, mem_cons_self _ _⟩
id ┴└┘ └───────────┘
src └┘ └───────────┘
typ ┴└┘ └───────────┘
160
161 theorem length_pos_iff_exists_mem {l : list α} : 0 < length l ↔ ∃ a, a ∈ l :=
id └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴
162 ⟨exists_mem_of_length_pos, λ ⟨a, h⟩, length_pos_of_mem h⟩
id └──────────────────────┘ ┴ ┴ └───────────────┘
src └──────────────────────┘ └───────────────┘
typ └──────────────────────┘ ┴ ┴ └───────────────┘
163
164 theorem ne_nil_of_length_pos {l : list α} : 0 < length l → l ≠ [] :=
id └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ └┘
src └──┘ ┴ └────┘ ┴ └┘
typ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ └┘
165 λ h1 h2, lt_irrefl 0 ((length_eq_zero.2 h2).subst h1)
id └┘ └┘ └───────┘ └────────────┘┴ └┘ └───┘ └┘
src └───────┘ └────────────┘┴ └───┘
typ └┘ └┘ └───────┘ └────────────┘┴ └┘ └───┘ └┘
166
167 theorem length_pos_of_ne_nil {l : list α} : l ≠ [] → 0 < length l :=
id └──┘ ┴ ┴ ┴ └┘ ┴ └────┘ ┴
src └──┘ ┴ └┘ ┴ └────┘
typ └──┘ ┴ ┴ ┴ └┘ ┴ └────┘ ┴
168 λ h, pos_iff_ne_zero.2 $ λ h0, h $ length_eq_zero.1 h0
id ┴ └─────────────┘┴ └┘ ┴ └────────────┘┴ └┘
src └─────────────┘┴ └────────────┘┴
typ ┴ └─────────────┘┴ └┘ ┴ └────────────┘┴ └┘
169
170 theorem length_pos_iff_ne_nil {l : list α} : 0 < length l ↔ l ≠ [] :=
id └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └┘
src └──┘ ┴ └────┘ ┴ ┴ └┘
typ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └┘
171 ⟨ne_nil_of_length_pos, length_pos_of_ne_nil⟩
id └──────────────────┘ └──────────────────┘
src └──────────────────┘ └──────────────────┘
typ └──────────────────┘ └──────────────────┘
172
173 theorem length_eq_one {l : list α} : length l = 1 ↔ ∃ a, l = [a] :=
id └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴┴┴
src └──┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴┴┴
174 ⟨match l with [a], _ := ⟨a, rfl⟩ end, λ ⟨a, e⟩, e.symm ▸ rfl⟩
id ┴ ┴┴┴ └─┘ ┴ ┴ └───┘ ┴ └─┘
src ┴ ┴ └─┘ └───┘ ┴ └─┘
typ ┴ ┴┴┴ └─┘ ┴ ┴ └───┘ ┴ └─┘
175
176 lemma exists_of_length_succ {n} :
177 ∀ l : list α, l.length = n + 1 → ∃ h t, l = h :: t
id ┴ └──┘ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ └┘ ┴
src └──┘ └─────┘ ┴ ┴ ┴ ┴ ┴ └┘
typ ┴ └──┘ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ └┘ ┴
178 | [] H := absurd H.symm $ succ_ne_zero n
id └┘ ┴ └────┘ └───┘ └──────────┘ ┴
src └┘ └────┘ └───┘ └──────────┘
typ └┘ ┴ └────┘ └───┘ └──────────┘ ┴
179 | (h :: t) H := ⟨h, t, rfl⟩
id ┴ └┘ ┴ └─┘
src └┘ └─┘
typ ┴ └┘ ┴ └─┘
180
181 lemma injective_length_iff : injective (list.length : list α → ℕ) ↔ subsingleton α :=
id └───────┘ └─────────┘ └──┘ ┴ ┴ ┴ └──────────┘ ┴
src └───────┘ └─────────┘ └──┘ ┴ ┴ └──────────┘
typ └───────┘ └─────────┘ └──┘ ┴ ┴ ┴ └──────────┘ ┴
182 begin
st └─────
183 split,
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
st ──────┘└─
184 { intro h, refine ⟨λ x y, _⟩, suffices : [x] = [y], { simpa using this }, apply h, refl },
id ┴ ┴ ┴┴┴ └──┘
src └─────┘ └─────┘ └──────┘ └─────────┘ ┴┴┴┴ ┴ └──────────┘ ┴ └────┘ └───┘
typ └─────┘ └─────┘ └──────┘ └─────────┘ ┴ ┴┴┴┴┴┴ └──────────┘└──┘┴ └────┘ └───┘
doc └─────┘ └─────┘ └──────┘ └─────────┘ ┴ ┴ └──────────┘ ┴ └────┘ └───┘
txt └─────┘ └─────┘ └──────┘ └─────────┘ ┴ ┴ └──────────┘ ┴ └────┘ └───┘
par └─────┘ └─────┘ └──────┘ └─────────┘ ┴ ┴ └──────────┘ ┴ └────┘ └───┘
pid └┘ ┴ └──────┘ └───────┘└┘ ┴ ┴ ┴└────┘ ┴ ┴ ┴
st ───┘└─────┘└─────────────────┘└────────────────────┘└──┘└───────────────┘└┘└──────┘└─────┘└┘└
185 { intros hα l1 l2 hl, induction l1 generalizing l2; cases l2,
id └┘ └┘
src └────────────────┘ └────────┘ └──────────────┘ └────┘
typ └────────────────┘ └────────┘└┘└──────────────┘ └────┘└┘
doc └────────────────┘ └────────┘ └──────────────┘ └────┘
txt └────────────────┘ └────────┘ └──────────────┘ └────┘
par └────────────────┘ └────────┘ └──────────────┘ └────┘
pid └──────────┘ ┴ ┴└─────────────┘ ┴
st ─────────────────────┘└──────────────────────────────────────┘└─
186 { refl }, { cases hl }, { cases hl },
id └┘ └┘
src └───┘ └────┘ ┴ └────┘ ┴
typ └───┘ └────┘└┘┴ └────┘└┘┴
doc └───┘ └────┘ ┴ └────┘ ┴
txt └───┘ └────┘ ┴ └────┘ ┴
par └───┘ └────┘ ┴ └────┘ ┴
pid ┴ ┴ ┴ ┴ ┴
st ─────┘└───┘└┘└─┘└───────┘└┘└─┘└───────┘└┘└
187 congr, exactI subsingleton.elim _ _, apply l1_ih, simpa using hl }
id └───────────────┘ └┘
src └───┘ └─────┘└───────────────┘└──┘ └────┘ └──────────┘ ┴
typ └───┘ └─────┘└───────────────┘└──┘ └────┘ └──────────┘└┘┴
doc └─────┘ └──┘ └────┘ └──────────┘ ┴
txt └───┘ └─────┘ └──┘ └────┘ └──────────┘ ┴
par └───┘ └─────┘ └──┘ └────┘ └──────────┘ ┴
pid ┴ └──┘ ┴ ┴└────┘ ┴
st ────────┘└────────────────────────────┘└───────────┘└───────────────┘└─
188 end
st ──┘
189
190 lemma injective_length [subsingleton α] : injective (length : list α → ℕ) :=
id └──────────┘ ┴ └───────┘ └────┘ └──┘ ┴ ┴
src └──────────┘ └───────┘ └────┘ └──┘ ┴
typ └──────────┘ ┴ └───────┘ └────┘ └──┘ ┴ ┴
191 injective_length_iff.mpr $ by apply_instance
id └──────────────────┘└──┘
src └──────────────────┘└──┘ └──────────────
typ └──────────────────┘└──┘ └──────────────
doc └──────────────
txt └──────────────
par └──────────────
pid └
st └───────────────
192
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
193 /- set-theoretic notation of lists -/
src ──────────────────────────────────────
typ ──────────────────────────────────────
doc ──────────────────────────────────────
txt ──────────────────────────────────────
par ──────────────────────────────────────
pid ──────────────────────────────────────
st ──────────────────────────────────────
194
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
195 lemma empty_eq : (∅ : list α) = [] := by refl
id ┴ └──┘ ┴ ┴ └┘
src ┴ └──┘ ┴ └┘ └───┘
typ ┴ └──┘ ┴ ┴ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
196 lemma singleton_eq [decidable_eq α] (x : α) : ({x} : list α) = [x] := by refl
id └──────────┘ ┴ ┴ ┴┴ └──┘ ┴ ┴ ┴┴┴
src └──────────┘ ┴ └──┘ ┴ ┴ ┴ └───┘
typ └──────────┘ ┴ ┴ ┴┴ └──┘ ┴ ┴ ┴┴┴ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
197 lemma insert_neg [decidable_eq α] {x : α} {l : list α} (h : x ∉ l) :
id └──────────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──────────┘ └──┘ ┴
typ └──────────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
198 has_insert.insert x l = x :: l :=
id └───────────────┘ ┴ ┴ ┴ ┴ └┘ ┴
src └───────────────┘ ┴ └┘
typ └───────────────┘ ┴ ┴ ┴ ┴ └┘ ┴
199 if_neg h
id └────┘ ┴
src └────┘
typ └────┘ ┴
200 lemma insert_pos [decidable_eq α] {x : α} {l : list α} (h : x ∈ l) :
id └──────────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──────────┘ └──┘ ┴
typ └──────────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
201 has_insert.insert x l = l :=
id └───────────────┘ ┴ ┴ ┴ ┴
src └───────────────┘ ┴
typ └───────────────┘ ┴ ┴ ┴ ┴
202 if_pos h
id └────┘ ┴
src └────┘
typ └────┘ ┴
203 lemma doubleton_eq [decidable_eq α] {x y : α} (h : x ≠ y) : ({x, y} : list α) = [y, x] :=
id └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴┴┴ ┴ └──┘ ┴ ┴ ┴┴┴ ┴┴
src └──────────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
typ └──────────┘ ┴ ┴ ┴ ┴ ┴ ┴┴┴ ┴ └──┘ ┴ ┴ ┴┴┴ ┴┴
204 by { rw [insert_neg, singleton_eq], show y ∉ [x], rw [mem_singleton], exact h.symm }
id └────────┘ └──────────┘ ┴ ┴ ┴┴┴ └───────────┘ └────┘
src └──┘└────────┘└┘└──────────┘┴ └───┘ ┴┴┴┴ ┴ └──┘└───────────┘┴ └────┘└────┘┴
typ └──┘└────────┘└┘└──────────┘┴ └───┘┴┴┴┴┴┴┴ └──┘└───────────┘┴ └────┘└────┘┴
doc └──┘ └┘ ┴ └───┘ ┴ ┴ └──┘ ┴ └────┘ ┴
txt └──┘ └┘ ┴ └───┘ ┴ ┴ └──┘ ┴ └────┘ ┴
par └──┘ └┘ ┴ └───┘ ┴ ┴ └──┘ ┴ └────┘ ┴
pid └┘ └┘ ┴ └───┘ ┴ ┴ └┘ ┴ ┴ ┴
st └───────────────┘└────────────┘└─────────────┘└─────────────────┘└──────────────┘└┘
205
206 /- bounded quantifiers over lists -/
207
208 theorem forall_mem_nil (p : α → Prop) : ∀ x ∈ @nil α, p x.
id ┴ ┴ └─┘ ┴ ┴ └┘
src ┴ └─┘
typ ┴ ┴ └─┘ ┴ ┴ └┘
209
210 @[simp] theorem forall_mem_cons' {p : α → Prop} {a : α} {l : list α} :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
doc └──┘
211 (∀ (x : α), x = a ∨ x ∈ l → p x) ↔ p a ∧ ∀ x ∈ l, p x :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
212 by simp only [or_imp_distrib, forall_and_distrib, forall_eq]
id └────────────┘ └────────────────┘ └───────┘
src └─────────┘└────────────┘└┘└────────────────┘└┘└───────┘└─
typ └─────────┘└────────────┘└┘└────────────────┘└┘└───────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └──────────────────────────────────────────────────────────
213
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
214 theorem forall_mem_cons {p : α → Prop} {a : α} {l : list α} :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
215 (∀ x ∈ a :: l, p x) ↔ p a ∧ ∀ x ∈ l, p x :=
id ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └┘ ┴ ┴
typ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
216 by simp only [mem_cons_iff, forall_mem_cons']
id └──────────┘ └──────────────┘
src └─────────┘└──────────┘└┘└──────────────┘└─
typ └─────────┘└──────────┘└┘└──────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └───────────────────────────────────────────
217
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
218 theorem forall_mem_of_forall_mem_cons {p : α → Prop} {a : α} {l : list α}
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
219 (h : ∀ x ∈ a :: l, p x) :
id ┴ ┴ └┘ ┴ ┴ ┴
src └┘
typ ┴ ┴ └┘ ┴ ┴ ┴
220 ∀ x ∈ l, p x :=
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
221 (forall_mem_cons.1 h).2
id └─────────────┘┴ ┴ ┴
src └─────────────┘┴ ┴
typ └─────────────┘┴ ┴ ┴
222
223 theorem forall_mem_singleton {p : α → Prop} {a : α} : (∀ x ∈ [a], p x) ↔ p a :=
id ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴
typ ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴
224 by simp only [mem_singleton, forall_eq]
id └───────────┘ └───────┘
src └─────────┘└───────────┘└┘└───────┘└─
typ └─────────┘└───────────┘└┘└───────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └─────────────────────────────────────
225
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
226 theorem forall_mem_append {p : α → Prop} {l₁ l₂ : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
227 (∀ x ∈ l₁ ++ l₂, p x) ↔ (∀ x ∈ l₁, p x) ∧ (∀ x ∈ l₂, p x) :=
id ┴ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴
src └┘ ┴ ┴
typ ┴ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴
228 by simp only [mem_append, or_imp_distrib, forall_and_distrib]
id └────────┘ └────────────┘ └────────────────┘
src └─────────┘└────────┘└┘└────────────┘└┘└────────────────┘└─
typ └─────────┘└────────┘└┘└────────────┘└┘└────────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────────────────
229
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
230 theorem not_exists_mem_nil (p : α → Prop) : ¬ ∃ x ∈ @nil α, p x.
id ┴ ┴ ┴ ┴ └─┘ ┴┴ ┴ └┘
src ┴ ┴ └─┘ ┴
typ ┴ ┴ ┴ ┴ └─┘ ┴┴ ┴ └┘
231
232 theorem exists_mem_cons_of {p : α → Prop} {a : α} (l : list α) (h : p a) :
id ┴ ┴ └──┘ ┴ ┴ ┴
src └──┘
typ ┴ ┴ └──┘ ┴ ┴ ┴
233 ∃ x ∈ a :: l, p x :=
id ┴ ┴ ┴ └┘ ┴┴ ┴ ┴
src ┴ └┘ ┴
typ ┴ ┴ ┴ └┘ ┴┴ ┴ ┴
234 bex.intro a (mem_cons_self _ _) h
id └───────┘ ┴ └───────────┘ ┴
src └───────┘ └───────────┘
typ └───────┘ ┴ └───────────┘ ┴
235
236 theorem exists_mem_cons_of_exists {p : α → Prop} {a : α} {l : list α} (h : ∃ x ∈ l, p x) :
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴┴ ┴ ┴
src └──┘ ┴ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴┴ ┴ ┴
237 ∃ x ∈ a :: l, p x :=
id ┴ ┴ ┴ └┘ ┴┴ ┴ ┴
src ┴ └┘ ┴
typ ┴ ┴ ┴ └┘ ┴┴ ┴ ┴
238 bex.elim h (λ x xl px, bex.intro x (mem_cons_of_mem _ xl) px)
id └──────┘ ┴ ┴ └┘ └┘ └───────┘ ┴ └─────────────┘ └┘ └┘
src └──────┘ └───────┘ └─────────────┘
typ └──────┘ ┴ ┴ └┘ └┘ └───────┘ ┴ └─────────────┘ └┘ └┘
239
240 theorem or_exists_of_exists_mem_cons {p : α → Prop} {a : α} {l : list α} (h : ∃ x ∈ a :: l, p x) :
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └┘ ┴┴ ┴ ┴
src └──┘ ┴ └┘ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └┘ ┴┴ ┴ ┴
241 p a ∨ ∃ x ∈ l, p x :=
id ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
src ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
242 bex.elim h (λ x xal px,
id └──────┘ ┴ ┴ └─┘ └┘
src └──────┘
typ └──────┘ ┴ ┴ └─┘ └┘
243 or.elim (eq_or_mem_of_mem_cons xal)
id └─────┘ └───────────────────┘ └─┘
src └─────┘ └───────────────────┘
typ └─────┘ └───────────────────┘ └─┘
244 (assume : x = a, begin rw ←this, left, exact px end)
id ┴ ┴ ┴ └──┘ └┘
src ┴ └──┘ └──┘ └────┘ ┴
typ ┴ ┴ ┴ └──┘└──┘ └──┘ └────┘└┘┴
doc └──┘ └──┘ └────┘ ┴
txt └──┘ └──┘ └────┘ ┴
par └──┘ └──┘ └────┘ ┴
pid └┘ ┴ ┴
st └────────────┘└────┘└─────────┘└─┘
245 (assume : x ∈ l, or.inr (bex.intro x this px)))
id ┴ ┴ ┴ └────┘ └───────┘ ┴ └──┘ └┘
src ┴ └────┘ └───────┘
typ ┴ ┴ ┴ └────┘ └───────┘ ┴ └──┘ └┘
246
247 @[simp] theorem exists_mem_cons_iff (p : α → Prop) (a : α) (l : list α) :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
doc └──┘
248 (∃ x ∈ a :: l, p x) ↔ p a ∨ ∃ x ∈ l, p x :=
id ┴ ┴ ┴ └┘ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
src ┴ └┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ └┘ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
249 iff.intro or_exists_of_exists_mem_cons
id └───────┘ └──────────────────────────┘
src └───────┘ └──────────────────────────┘
typ └───────┘ └──────────────────────────┘
250 (assume h, or.elim h (exists_mem_cons_of l) exists_mem_cons_of_exists)
id ┴ └─────┘ ┴ └────────────────┘ ┴ └───────────────────────┘
src └─────┘ └────────────────┘ └───────────────────────┘
typ ┴ └─────┘ ┴ └────────────────┘ ┴ └───────────────────────┘
251
252 /- list subset -/
253
254 theorem subset_def {l₁ l₂ : list α} : l₁ ⊆ l₂ ↔ ∀ ⦃a : α⦄, a ∈ l₁ → a ∈ l₂ := iff.rfl
id └──┘ ┴ └┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘ └─────┘
src └──┘ ┴ ┴ ┴ ┴ └─────┘
typ └──┘ ┴ └┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘ └─────┘
255
256 theorem subset_append_of_subset_left (l l₁ l₂ : list α) : l ⊆ l₁ → l ⊆ l₁++l₂ :=
id └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘└┘└┘
src └──┘ ┴ ┴ └┘
typ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘└┘└┘
257 λ s, subset.trans s $ subset_append_left _ _
id ┴ └──────────┘ ┴ └────────────────┘
src └──────────┘ └────────────────┘
typ ┴ └──────────┘ ┴ └────────────────┘
258
259 theorem subset_append_of_subset_right (l l₁ l₂ : list α) : l ⊆ l₂ → l ⊆ l₁++l₂ :=
id └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘└┘└┘
src └──┘ ┴ ┴ └┘
typ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘└┘└┘
260 λ s, subset.trans s $ subset_append_right _ _
id ┴ └──────────┘ ┴ └─────────────────┘
src └──────────┘ └─────────────────┘
typ ┴ └──────────┘ ┴ └─────────────────┘
261
262 @[simp] theorem cons_subset {a : α} {l m : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
263 a::l ⊆ m ↔ a ∈ m ∧ l ⊆ m :=
id ┴└┘┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └┘ ┴ ┴ ┴ ┴ ┴
typ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
264 by simp only [subset_def, mem_cons_iff, or_imp_distrib, forall_and_distrib, forall_eq]
id └────────┘ └──────────┘ └────────────┘ └────────────────┘ └───────┘
src └─────────┘└────────┘└┘└──────────┘└┘└────────────┘└┘└────────────────┘└┘└───────┘└─
typ └─────────┘└────────┘└┘└──────────┘└┘└────────────┘└┘└────────────────┘└┘└───────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────────────────────────
265
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
266 theorem cons_subset_of_subset_of_mem {a : α} {l m : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
267 (ainm : a ∈ m) (lsubm : l ⊆ m) : a::l ⊆ m :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴└┘┴ ┴ ┴
src ┴ ┴ └┘ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴└┘┴ ┴ ┴
268 cons_subset.2 ⟨ainm, lsubm⟩
id └─────────┘┴ └──┘ └───┘
src └─────────┘┴
typ └─────────┘┴ └──┘ └───┘
269
270 theorem append_subset_of_subset_of_subset {l₁ l₂ l : list α} (l₁subl : l₁ ⊆ l) (l₂subl : l₂ ⊆ l) :
id └──┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴
src └──┘ ┴ ┴
typ └──┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴
271 l₁ ++ l₂ ⊆ l :=
id └┘ └┘ └┘ ┴ ┴
src └┘ ┴
typ └┘ └┘ └┘ ┴ ┴
272 λ a h, (mem_append.1 h).elim (@l₁subl _) (@l₂subl _)
id ┴ ┴ └────────┘┴ ┴ └──┘ └────┘ └────┘
src └────────┘┴ └──┘
typ ┴ ┴ └────────┘┴ ┴ └──┘ └────┘ └────┘
273
274 @[simp] theorem append_subset_iff {l₁ l₂ l : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
275 l₁ ++ l₂ ⊆ l ↔ l₁ ⊆ l ∧ l₂ ⊆ l :=
id └┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴
src └┘ ┴ ┴ ┴ ┴ ┴
typ └┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴
276 begin
st └─────
277 split,
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
st ──────┘└─
278 { intro h, simp only [subset_def] at *, split; intros; simp* },
id └────────┘
src └─────┘ └─────────┘└────────┘└────┘ └───┘ └────┘ └────┘
typ └─────┘ └─────────┘└────────┘└────┘ └───┘ └────┘ └────┘
doc └─────┘ └─────────┘ └────┘ └───┘ └────┘ └────┘
txt └─────┘ └─────────┘ └────┘ └───┘ └────┘ └────┘
par └─────┘ └─────────┘ └────┘ └───┘ └────┘ └────┘
pid └┘ ┴└──┘└┘ ┴┴└──┘ ┴┴
st ───┘└─────┘└───────────────────────────┘└─────────────────────┘└┘└
279 { rintro ⟨h1, h2⟩, apply append_subset_of_subset_of_subset h1 h2 }
id └───────────────────────────────┘ └┘ └┘
src └─────────────┘ └────┘└───────────────────────────────┘┴ ┴ ┴
typ └─────────────┘ └────┘└───────────────────────────────┘┴└┘┴└┘┴
doc └─────────────┘ └────┘ ┴ ┴ ┴
txt └─────────────┘ └────┘ ┴ ┴ ┴
par └─────────────┘ └────┘ ┴ ┴ ┴
pid └───────┘ ┴ ┴ ┴ ┴
st ──────────────────┘└──────────────────────────────────────────────┘└─
280 end
st ──┘
281
282 theorem eq_nil_of_subset_nil : ∀ {l : list α}, l ⊆ [] → l = []
id ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘
src └──┘ ┴ └┘ ┴ └┘
typ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘
283 | [] s := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
284 | (a::l) s := false.elim $ s $ mem_cons_self a l
id ┴└┘┴ ┴ └────────┘ └───────────┘
src └┘ └────────┘ └───────────┘
typ ┴└┘┴ ┴ └────────┘ └───────────┘
285
286 theorem eq_nil_iff_forall_not_mem {l : list α} : l = [] ↔ ∀ a, a ∉ l :=
id └──┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴
287 show l = [] ↔ l ⊆ [], from ⟨λ e, e ▸ subset.refl _, eq_nil_of_subset_nil⟩
id ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─────────┘ └──────────────────┘
src ┴ └┘ ┴ ┴ └┘ ┴ └─────────┘ └──────────────────┘
typ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─────────┘ └──────────────────┘
288
289 theorem map_subset {l₁ l₂ : list α} (f : α → β) (H : l₁ ⊆ l₂) : map f l₁ ⊆ map f l₂ :=
id └──┘ ┴ ┴ ┴ └┘ ┴ └┘ └─┘ ┴ └┘ ┴ └─┘ ┴ └┘
src └──┘ ┴ └─┘ ┴ └─┘
typ └──┘ ┴ ┴ ┴ └┘ ┴ └┘ └─┘ ┴ └┘ ┴ └─┘ ┴ └┘
290 λ x, by simp only [mem_map, not_and, exists_imp_distrib, and_imp]; exact λ a h e, ⟨a, H h, e⟩
id ┴ └─────┘ └─────┘ └────────────────┘ └─────┘ ┴
src └─────────┘└─────┘└┘└─────┘└┘└────────────────┘└┘└─────┘┴ └────┘ └──────┘ └┘ ┴ └┘ └─
typ ┴ └─────────┘└─────┘└┘└─────┘└┘└────────────────┘└┘└─────┘┴ └────┘ └──────┘ └┘┴┴ └┘ └─
doc └─────────┘ └┘ └┘ └┘ ┴ └────┘ └──────┘ └┘ ┴ └┘ └─
txt └─────────┘ └┘ └┘ └┘ ┴ └────┘ └──────┘ └┘ ┴ └┘ └─
par └─────────┘ └┘ └┘ └┘ ┴ └────┘ └──────┘ └┘ ┴ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ ┴ └──────┘ └┘ ┴ └┘ ┴└
st └──────────────────────────────────────────────────────────────────────────────────────
291
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
292 theorem map_subset_iff {l₁ l₂ : list α} (f : α → β) (h : injective f) : map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ :=
id └──┘ ┴ ┴ ┴ └───────┘ ┴ └─┘ ┴ └┘ ┴ └─┘ ┴ └┘ ┴ └┘ ┴ └┘
src └──┘ └───────┘ └─┘ ┴ └─┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ └───────┘ ┴ └─┘ ┴ └┘ ┴ └─┘ ┴ └┘ ┴ └┘ ┴ └┘
293 begin
st └─────
294 refine ⟨_, map_subset f⟩, intros h2 x hx,
id └────────┘ ┴
src └─────┘ └─┘└────────┘┴ ┴ └────────────┘
typ └─────┘ └─┘└────────┘┴┴┴ └────────────┘
doc └─────┘ └─┘ ┴ ┴ └────────────┘
txt └─────┘ └─┘ ┴ ┴ └────────────┘
par └─────┘ └─┘ ┴ ┴ └────────────┘
pid ┴ └─┘ ┴ ┴ └──────┘
st ─────────────────────────┘└──────────────┘└─
295 rcases mem_map.1 (h2 (mem_map_of_mem f hx)) with ⟨x', hx', hxx'⟩,
id └─────┘ └┘ └────────────┘ ┴ └┘
src └─────┘└─────┘└─┘ ┴ └────────────┘┴ ┴ └─────────────────────┘
typ └─────┘└─────┘└─┘ └┘┴ └────────────┘┴┴┴└┘└─────────────────────┘
doc └─────┘ └─┘ ┴ ┴ ┴ └─────────────────────┘
txt └─────┘ └─┘ ┴ ┴ ┴ └─────────────────────┘
par └─────┘ └─┘ ┴ ┴ ┴ └─────────────────────┘
pid ┴ └─┘ ┴ ┴ ┴ └─────────────────────┘
st ─────────────────────────────────────────────────────────────────┘└─
296 cases h hxx', exact hx'
id ┴ └──┘ └─┘
src └────┘ ┴ └────┘ ┴
typ └────┘┴┴└──┘ └────┘└─┘┴
doc └────┘ ┴ └────┘ ┴
txt └────┘ ┴ └────┘ ┴
par └────┘ ┴ └────┘ ┴
pid ┴ ┴ ┴ ┴
st ─────────────┘└──────────┘
297 end
st └─┘
298
299 /- append -/
300
301 lemma append_eq_has_append {L₁ L₂ : list α} : list.append L₁ L₂ = L₁ ++ L₂ := rfl
id └──┘ ┴ └─────────┘ └┘ └┘ ┴ └┘ └┘ └┘ └─┘
src └──┘ └─────────┘ ┴ └┘ └─┘
typ └──┘ ┴ └─────────┘ └┘ └┘ ┴ └┘ └┘ └┘ └─┘
302
303 theorem append_ne_nil_of_ne_nil_left (s t : list α) : s ≠ [] → s ++ t ≠ [] :=
id └──┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
src └──┘ ┴ └┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
304 by induction s; intros; contradiction
id ┴
src └────────┘ └────┘ └─────────────
typ └────────┘┴ └────┘ └─────────────
doc └────────┘ └────┘ └─────────────
txt └────────┘ └────┘ └─────────────
par └────────┘ └────┘ └─────────────
pid ┴ └
st └───────────────────────────────────
305
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
306 theorem append_ne_nil_of_ne_nil_right (s t : list α) : t ≠ [] → s ++ t ≠ [] :=
id └──┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
src └──┘ ┴ └┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
307 by induction s; intros; contradiction
id ┴
src └────────┘ └────┘ └─────────────
typ └────────┘┴ └────┘ └─────────────
doc └────────┘ └────┘ └─────────────
txt └────────┘ └────┘ └─────────────
par └────────┘ └────┘ └─────────────
pid ┴ └
st └───────────────────────────────────
308
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
309 theorem append_foldl (f : α → β → α) (a : α) (s t : list β) : foldl f a (s ++ t) = foldl f (foldl f a s) t :=
id ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └┘ ┴ ┴ └───┘ ┴ └───┘ ┴ ┴ ┴ ┴
src └──┘ └───┘ └┘ ┴ └───┘ └───┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └┘ ┴ ┴ └───┘ ┴ └───┘ ┴ ┴ ┴ ┴
310 by {induction s with b s H generalizing a, refl, simp only [foldl, cons_append], rw H _}
id ┴ └───┘ └─────────┘ ┴
src └────────┘ └────────────────────────┘ └──┘ └─────────┘└───┘└┘└─────────┘┴ └─┘ └┘
typ └────────┘┴└────────────────────────┘ └──┘ └─────────┘└───┘└┘└─────────┘┴ └─┘┴└┘
doc └────────┘ └────────────────────────┘ └──┘ └─────────┘ └┘ ┴ └─┘ └┘
txt └────────┘ └────────────────────────┘ └──┘ └─────────┘ └┘ ┴ └─┘ └┘
par └────────┘ └────────────────────────┘ └──┘ └─────────┘ └┘ ┴ └─┘ └┘
pid ┴ ┴└────────┘└─────────────┘ ┴└──┘└┘ └┘ ┴ ┴ └┘
st └─────────────────────────────────────┘└────┘└──────────────────────────────┘└──────┘└┘
311
312 theorem append_foldr (f : α → β → β) (a : β) (s t : list α) : foldr f a (s ++ t) = foldr f (foldr f a t) s :=
id ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └┘ ┴ ┴ └───┘ ┴ └───┘ ┴ ┴ ┴ ┴
src └──┘ └───┘ └┘ ┴ └───┘ └───┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └┘ ┴ ┴ └───┘ ┴ └───┘ ┴ ┴ ┴ ┴
313 by {induction s with b s H generalizing a, refl, simp only [foldr, cons_append], rw H _}
id ┴ └───┘ └─────────┘ ┴
src └────────┘ └────────────────────────┘ └──┘ └─────────┘└───┘└┘└─────────┘┴ └─┘ └┘
typ └────────┘┴└────────────────────────┘ └──┘ └─────────┘└───┘└┘└─────────┘┴ └─┘┴└┘
doc └────────┘ └────────────────────────┘ └──┘ └─────────┘ └┘ ┴ └─┘ └┘
txt └────────┘ └────────────────────────┘ └──┘ └─────────┘ └┘ ┴ └─┘ └┘
par └────────┘ └────────────────────────┘ └──┘ └─────────┘ └┘ ┴ └─┘ └┘
pid ┴ ┴└────────┘└─────────────┘ ┴└──┘└┘ └┘ ┴ ┴ └┘
st └─────────────────────────────────────┘└────┘└──────────────────────────────┘└──────┘└┘
314
315 @[simp] lemma append_eq_nil {p q : list α} : (p ++ q) = [] ↔ p = [] ∧ q = [] :=
id └──┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ └┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘
typ └──┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
316 by cases p; simp only [nil_append, cons_append, eq_self_iff_true, true_and, false_and]
id ┴ └────────┘ └─────────┘ └──────────────┘ └──────┘ └───────┘
src └────┘ └─────────┘└────────┘└┘└─────────┘└┘└──────────────┘└┘└──────┘└┘└───────┘└─
typ └────┘┴ └─────────┘└────────┘└┘└─────────┘└┘└──────────────┘└┘└──────┘└┘└───────┘└─
doc └────┘ └─────────┘ └┘ └┘ └┘ └┘ └─
txt └────┘ └─────────┘ └┘ └┘ └┘ └┘ └─
par └────┘ └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴ ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────────────────────────
317
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
318 @[simp] lemma nil_eq_append_iff {a b : list α} : [] = a ++ b ↔ a = [] ∧ b = [] :=
id └──┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ └┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘
typ └──┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
319 by rw [eq_comm, append_eq_nil]
id └─────┘ └───────────┘
src └──┘└─────┘└┘└───────────┘└─
typ └──┘└─────┘└┘└───────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └──────────┘└─────────────┘┴└
320
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
321 lemma append_eq_cons_iff {a b c : list α} {x : α} :
id └──┘ ┴ ┴
src └──┘
typ └──┘ ┴ ┴
322 a ++ b = x :: c ↔ (a = [] ∧ b = x :: c) ∨ (∃a', a = x :: a' ∧ c = a' ++ b) :=
id ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴
src └┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘
typ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴
323 by cases a; simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, eq_self_iff_true,
id ┴ └───────┘ └─────┘ ┴ └────────┘ └─────────┘ └──────────────┘
src └────┘ └─────────┘└───────┘└┘ └─────┘└─┘ └┘└────────┘└┘└─────────┘└┘└──────────────┘└─
typ └────┘┴ └─────────┘└───────┘└┘ └─────┘└─┘┴└┘└────────┘└┘└─────────┘└┘└──────────────┘└─
doc └────┘ └─────────┘ └┘ └─┘ └┘ └┘ └┘ └─
txt └────┘ └─────────┘ └┘ └─┘ └┘ └┘ └┘ └─
par └────┘ └─────────┘ └┘ └─┘ └┘ └┘ └┘ └─
pid ┴ ┴└──┘└┘ └┘ └─┘ └┘ └┘ └┘ └─
st └────────────────────────────────────────────────────────────────────────────────────────
324 true_and, false_and, exists_false, false_or, or_false, exists_and_distrib_left, exists_eq_left']
id └──────┘ └───────┘ └──────────┘ └──────┘ └──────┘ └─────────────────────┘ └─────────────┘
src ─┘└──────┘└┘└───────┘└┘└──────────┘└┘└──────┘└┘└──────┘└┘└─────────────────────┘└┘└─────────────┘└─
typ ─┘└──────┘└┘└───────┘└┘└──────────┘└┘└──────┘└┘└──────┘└┘└─────────────────────┘└┘└─────────────┘└─
doc ─┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
txt ─┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
par ─┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
pid ─┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴└
st ───────────────────────────────────────────────────────────────────────────────────────────────────
325
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
326 lemma cons_eq_append_iff {a b c : list α} {x : α} :
id └──┘ ┴ ┴
src └──┘
typ └──┘ ┴ ┴
327 (x :: c : list α) = a ++ b ↔ (a = [] ∧ b = x :: c) ∨ (∃a', a = x :: a' ∧ c = a' ++ b) :=
id ┴ └┘ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴
src └┘ └──┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘
typ ┴ └┘ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴
328 by rw [eq_comm, append_eq_cons_iff]
id └─────┘ └────────────────┘
src └──┘└─────┘└┘└────────────────┘└─
typ └──┘└─────┘└┘└────────────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └──────────┘└──────────────────┘┴└
329
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
330 lemma append_eq_append_iff {a b c d : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
331 a ++ b = c ++ d ↔ (∃a', c = a ++ a' ∧ b = a' ++ d) ∨ (∃c', a = c ++ c' ∧ d = c' ++ b) :=
id ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴
src └┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘
typ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ └┘ ┴
332 begin
st └─────
333 induction a generalizing c,
id ┴
src └────────┘ └─────────────┘
typ └────────┘┴└─────────────┘
doc └────────┘ └─────────────┘
txt └────────┘ └─────────────┘
par └────────┘ └─────────────┘
pid ┴ ┴└────────────┘
st ───────────────────────────┘└─
334 case nil { rw nil_append, split,
id └────────┘
src └─────────┘└─┘└────────┘└┘└───┘└─
typ └─────────┘└─┘└────────┘└┘└───┘└─
doc └─────────┘└─┘ └┘└───┘└─
txt └─────────┘└─┘ └┘└───┘└─
par └─────────┘└─┘ └┘└───┘└─
pid └──┘┴└───┘ └────────
st ───────────┘└────────────┘└─────┘└─
335 { rintro rfl, left, exact ⟨_, rfl, rfl⟩ },
id └─┘
src ─────┘└────────┘└┘└──┘└┘└────┘ └─┘ └┘└─┘└┘└──
typ ─────┘└────────┘└┘└──┘└┘└────┘ └─┘ └┘└─┘└┘└──
doc ─────┘└────────┘└┘└──┘└┘└────┘ └─┘ └┘ └┘└──
txt ─────┘└────────┘└┘└──┘└┘└────┘ └─┘ └┘ └┘└──
par ─────┘└────────┘└┘└──┘└┘└────┘ └─┘ └┘ └┘└──
pid ─────────────────────────────┘ └─┘ └┘ └────
st ────┘└─────────┘└────┘└────────────────────┘┴└─
336 { rintro (⟨a', rfl, rfl⟩ | ⟨a', H, rfl⟩), {refl}, {rw [← append_assoc, ← H], refl} } },
id └──────────┘ ┴
src ─────┘└────────────────────────────────────┘└─┘└──┘└──┘└────┘└──────────┘└──┘ ┴└┘└──┘└───┘
typ ─────┘└────────────────────────────────────┘└─┘└──┘└──┘└────┘└──────────┘└──┘┴┴└┘└──┘└───┘
doc ─────┘└────────────────────────────────────┘└─┘└──┘└──┘└────┘ └──┘ ┴└┘└──┘└───┘
txt ─────┘└────────────────────────────────────┘└─┘└──┘└──┘└────┘ └──┘ ┴└┘└──┘└───┘
par ─────┘└────────────────────────────────────┘└─┘└──┘└──┘└────┘ └──┘ ┴└┘└──┘└───┘
pid ────────────────────────────────────────────────────────────┘ └──┘ └──────────┘
st ───────────────────────────────────────────┘└─────┘┴└───────────────────┘└───┘└─────┘└────┘└
337 case cons : a as ih {
src └─────────────────────
typ └─────────────────────
doc └─────────────────────
txt └─────────────────────
par └─────────────────────
pid └───┘└────────┘└──
st ──────────────────────┘└
338 cases c,
id ┴
src ───┘└────┘ └─
typ ───┘└────┘┴└─
doc ───┘└────┘ └─
txt ───┘└────┘ └─
par ───┘└────┘ └─
pid ─────────┘ └─
st ──────────┘└─
339 { simp only [cons_append, nil_append, false_and, exists_false, false_or, exists_eq_left'], exact eq_comm },
id └─────────┘ └────────┘ └───────┘ └──────────┘ └──────┘ └─────────────┘ └─────┘
src ─────┘└─────────┘└─────────┘└┘└────────┘└┘└───────┘└┘└──────────┘└┘└──────┘└┘└─────────────┘┴└┘└────┘└─────┘┴└──
typ ─────┘└─────────┘└─────────┘└┘└────────┘└┘└───────┘└┘└──────────┘└┘└──────┘└┘└─────────────┘┴└┘└────┘└─────┘┴└──
doc ─────┘└─────────┘ └┘ └┘ └┘ └┘ └┘ ┴└┘└────┘ ┴└──
txt ─────┘└─────────┘ └┘ └┘ └┘ └┘ └┘ ┴└┘└────┘ ┴└──
par ─────┘└─────────┘ └┘ └┘ └┘ └┘ └┘ ┴└┘└────┘ ┴└──
pid ────────────────┘ └┘ └┘ └┘ └┘ └┘ └───────┘ └───
st ────┘└──────────────────────────────────────────────────────────────────────────────────────┘└──────────────┘┴└─
340 { simp only [cons_append, @eq_comm _ a, ih, and_assoc, and_or_distrib_left, exists_and_distrib_left] } }
id └─────────┘ └─────┘ ┴ └───────┘ └─────────────────┘ └─────────────────────┘
src ─────┘└─────────┘└─────────┘└┘ └─────┘└─┘ └┘ └┘└───────┘└┘└─────────────────┘└┘└─────────────────────┘└┘└──┘
typ ─────┘└─────────┘└─────────┘└┘ └─────┘└─┘┴└┘└┘└┘└───────┘└┘└─────────────────┘└┘└─────────────────────┘└┘└──┘
doc ─────┘└─────────┘ └┘ └─┘ └┘ └┘ └┘ └┘ └┘└──┘
txt ─────┘└─────────┘ └┘ └─┘ └┘ └┘ └┘ └┘ └┘└──┘
par ─────┘└─────────┘ └┘ └─┘ └┘ └┘ └┘ └┘ └┘└──┘
pid ────────────────┘ └┘ └─┘ └┘ └┘ └┘ └┘ └───┘┴
st ────────────────────────────────────────────────────────────────────────────────────────────────────────┘└─┘┴
341 end
st └─┘
342
343 @[simp] theorem split_at_eq_take_drop : ∀ (n : ℕ) (l : list α), split_at n l = (take n l, drop n l)
id ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ ┴└──┘ ┴ ┴ └──┘ ┴ ┴
src ┴ └──┘ └──────┘ ┴ ┴└──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ ┴└──┘ ┴ ┴ └──┘ ┴ ┴
doc └──┘ └──────┘
344 | 0 a := rfl
id └─┘
src └─┘
typ └─┘
345 | (succ n) [] := rfl
id └──┘ └┘ └─┘
src └──┘ └┘ └─┘
typ └──┘ └┘ └─┘
346 | (succ n) (x :: xs) := by simp only [split_at, split_at_eq_take_drop n xs, take, drop]
id └──┘ └┘ └──────┘ └───────────────────┘ ┴ └┘ └──┘ └──┘
src └──┘ └┘ └─────────┘└──────┘└┘ ┴ ┴ └┘└──┘└┘└──┘└─
typ └──┘ └┘ └─────────┘└──────┘└┘└───────────────────┘┴┴┴└┘└┘└──┘└┘└──┘└─
doc └─────────┘└──────┘└┘ ┴ ┴ └┘ └┘ └─
txt └─────────┘ └┘ ┴ ┴ └┘ └┘ └─
par └─────────┘ └┘ ┴ ┴ └┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴ ┴ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────
347
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
348 @[simp] theorem take_append_drop : ∀ (n : ℕ) (l : list α), take n l ++ drop n l = l
id ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ └┘ └──┘ ┴ ┴ ┴ ┴
src ┴ └──┘ └──┘ └┘ └──┘ ┴
typ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ └┘ └──┘ ┴ ┴ ┴ ┴
doc └──┘
349 | 0 a := rfl
id └─┘
src └─┘
typ └─┘
350 | (succ n) [] := rfl
id └──┘ └┘ └─┘
src └──┘ └┘ └─┘
typ └──┘ └┘ └─┘
351 | (succ n) (x :: xs) := congr_arg (cons x) $ take_append_drop n xs
id └──┘ ┴ ┴ └┘ └┘ └───────┘ └──┘ └──────────────┘
src └──┘ └┘ └───────┘ └──┘
typ └──┘ ┴ ┴ └┘ └┘ └───────┘ └──┘ └──────────────┘
352
353 -- TODO(Leo): cleanup proof after arith dec proc
354 theorem append_inj : ∀ {s₁ s₂ t₁ t₂ : list α}, s₁ ++ t₁ = s₂ ++ t₂ → length s₁ = length s₂ → s₁ = s₂ ∧ t₁ = t₂
id ┴ └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘ ┴ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ └────┘ ┴ └────┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘ ┴ └┘ ┴ └┘
355 | [] [] t₁ t₂ h hl := ⟨rfl, h⟩
id └┘ └┘ ┴ └─┘
src └┘ └┘ └─┘
typ └┘ └┘ ┴ └─┘
356 | (a::s₁) [] t₁ t₂ h hl := list.no_confusion $ eq_nil_of_length_eq_zero hl
id └┘ └┘ └┘ └───────────────┘ └──────────────────────┘
src └┘ └┘ └───────────────┘ └──────────────────────┘
typ └┘ └┘ └┘ └───────────────┘ └──────────────────────┘
357 | [] (b::s₂) t₁ t₂ h hl := list.no_confusion $ eq_nil_of_length_eq_zero hl.symm
id └┘ └┘ └┘ └───────────────┘ └──────────────────────┘ └───┘
src └┘ └┘ └───────────────┘ └──────────────────────┘ └───┘
typ └┘ └┘ └┘ └───────────────┘ └──────────────────────┘ └───┘
358 | (a::s₁) (b::s₂) t₁ t₂ h hl := list.no_confusion h $ λab hap,
id └┘└┘ └┘└┘ └┘ └┘ ┴ └┘ └───────────────┘ └┘ └─┘
src └┘ └┘ └───────────────┘
typ └┘└┘ └┘└┘ └┘ └┘ ┴ └┘ └───────────────┘ └┘ └─┘
359 let ⟨e1, e2⟩ := @append_inj s₁ s₂ t₁ t₂ hap (succ.inj hl) in
id └─┘ └────────┘ └─┘ └──────┘
src └──────┘
typ └─┘ └────────┘ └─┘ └──────┘
360 by rw [ab, e1, e2]; exact ⟨rfl, rfl⟩
id └┘ └┘ └┘ └─┘
src └──┘ └┘ └┘ ┴ └────┘ └┘└─┘└─
typ └──┘└┘└┘└┘└┘└┘┴ └────┘ └┘└─┘└─
doc └──┘ └┘ └┘ ┴ └────┘ └┘ └─
txt └──┘ └┘ └┘ ┴ └────┘ └┘ └─
par └──┘ └┘ └┘ ┴ └────┘ └┘ └─
pid └┘ └┘ └┘ ┴ ┴ └┘ ┴└
st └─────┘└──┘└──┘┴└──────────────────
361
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
362 theorem append_inj_left {s₁ s₂ t₁ t₂ : list α} (h : s₁ ++ t₁ = s₂ ++ t₂) (hl : length s₁ = length s₂) : t₁ = t₂ :=
id └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
363 (append_inj h hl).right
id └────────┘ ┴ └┘ └───┘
src └────────┘ └───┘
typ └────────┘ ┴ └┘ └───┘
364
365 theorem append_inj_right {s₁ s₂ t₁ t₂ : list α} (h : s₁ ++ t₁ = s₂ ++ t₂) (hl : length s₁ = length s₂) : s₁ = s₂ :=
id └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
366 (append_inj h hl).left
id └────────┘ ┴ └┘ └──┘
src └────────┘ └──┘
typ └────────┘ ┴ └┘ └──┘
367
368 theorem append_inj' {s₁ s₂ t₁ t₂ : list α} (h : s₁ ++ t₁ = s₂ ++ t₂) (hl : length t₁ = length t₂) : s₁ = s₂ ∧ t₁ = t₂ :=
id └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘ ┴ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ └────┘ ┴ └────┘ ┴ ┴ ┴
typ └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘ ┴ └┘ ┴ └┘
369 append_inj h $ @nat.add_right_cancel _ (length t₁) _ $
id └────────┘ ┴ └──────────────────┘ └────┘ └┘
src └────────┘ └──────────────────┘ └────┘
typ └────────┘ ┴ └──────────────────┘ └────┘ └┘
370 let hap := congr_arg length h in by simp only [length_append] at hap; rwa [← hl] at hap
id └─┘ └───────┘ └────┘ ┴ └───────────┘ └┘
src └───────┘ └────┘ └─────────┘└───────────┘└──────┘ └─────┘ └────────
typ └─┘ └───────┘ └────┘ ┴ └─────────┘└───────────┘└──────┘ └─────┘└┘└────────
doc └─────────┘ └──────┘ └─────┘ └────────
txt └─────────┘ └──────┘ └─────┘ └────────
par └─────────┘ └──────┘ └─────┘ └────────
pid ┴└──┘└┘ ┴┴└────┘ └──┘ ┴└─────┘└
st └──────────────────────────────────────┘└──┘┴└───────
371
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
372 theorem append_inj_left' {s₁ s₂ t₁ t₂ : list α} (h : s₁ ++ t₁ = s₂ ++ t₂) (hl : length t₁ = length t₂) : t₁ = t₂ :=
id └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
373 (append_inj' h hl).right
id └─────────┘ ┴ └┘ └───┘
src └─────────┘ └───┘
typ └─────────┘ ┴ └┘ └───┘
374
375 theorem append_inj_right' {s₁ s₂ t₁ t₂ : list α} (h : s₁ ++ t₁ = s₂ ++ t₂) (hl : length t₁ = length t₂) : s₁ = s₂ :=
id └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
376 (append_inj' h hl).left
id └─────────┘ ┴ └┘ └──┘
src └─────────┘ └──┘
typ └─────────┘ ┴ └┘ └──┘
377
378 theorem append_left_cancel {s t₁ t₂ : list α} (h : s ++ t₁ = s ++ t₂) : t₁ = t₂ :=
id └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ ┴
typ └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ └┘ └┘ ┴ └┘
379 append_inj_left h rfl
id └─────────────┘ ┴ └─┘
src └─────────────┘ └─┘
typ └─────────────┘ ┴ └─┘
380
381 theorem append_right_cancel {s₁ s₂ t : list α} (h : s₁ ++ t = s₂ ++ t) : s₁ = s₂ :=
id └──┘ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ ┴
typ └──┘ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └┘
382 append_inj_right' h rfl
id └───────────────┘ ┴ └─┘
src └───────────────┘ └─┘
typ └───────────────┘ ┴ └─┘
383
384 theorem append_left_inj {t₁ t₂ : list α} (s) : s ++ t₁ = s ++ t₂ ↔ t₁ = t₂ :=
id └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ ┴ ┴
typ └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └┘
385 ⟨append_left_cancel, congr_arg _⟩
id └────────────────┘ └───────┘
src └────────────────┘ └───────┘
typ └────────────────┘ └───────┘
386
387 theorem append_right_inj {s₁ s₂ : list α} (t) : s₁ ++ t = s₂ ++ t ↔ s₁ = s₂ :=
id └──┘ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ ┴ └┘
src └──┘ └┘ ┴ └┘ ┴ ┴
typ └──┘ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ ┴ └┘
388 ⟨append_right_cancel, congr_arg _⟩
id └─────────────────┘ └───────┘
src └─────────────────┘ └───────┘
typ └─────────────────┘ └───────┘
389
390 theorem map_eq_append_split {f : α → β} {l : list α} {s₁ s₂ : list β}
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
391 (h : map f l = s₁ ++ s₂) : ∃ l₁ l₂, l = l₁ ++ l₂ ∧ map f l₁ = s₁ ∧ map f l₂ = s₂ :=
id └─┘ ┴ ┴ ┴ └┘ └┘ └┘ ┴ └┘ └┘┴ ┴ ┴ └┘ └┘ └┘ ┴ └─┘ ┴ └┘ ┴ └┘ ┴ └─┘ ┴ └┘ ┴ └┘
src └─┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ └─┘ ┴ ┴ └─┘ ┴
typ └─┘ ┴ ┴ ┴ └┘ └┘ └┘ ┴ └┘ └┘┴ ┴ ┴ └┘ └┘ └┘ ┴ └─┘ ┴ └┘ ┴ └┘ ┴ └─┘ ┴ └┘ ┴ └┘
392 begin
st └─────
393 have := h, rw [← take_append_drop (length s₁) l] at this ⊢,
id ┴ └──────────────┘ └────┘ └┘ ┴
src └──────┘ └────┘└──────────────┘┴ └────┘┴ └┘ └─────────┘
typ └──────┘┴ └────┘└──────────────┘┴ └────┘┴└┘└┘┴└─────────┘
doc └──────┘ └────┘ ┴ ┴ └┘ └─────────┘
txt └──────┘ └────┘ ┴ ┴ └┘ └─────────┘
par └──────┘ └────┘ ┴ ┴ └┘ └─────────┘
pid └───┘└─┘ └──┘ ┴ ┴ └┘ ┴└────────┘
st ──────────┘└────────────────────────────────────┘┴└────────┘└─
394 rw map_append at this,
id └────────┘
src └─┘└────────┘└──────┘
typ └─┘└────────┘└──────┘
doc └─┘ └──────┘
txt └─┘ └──────┘
par └─┘ └──────┘
pid ┴ └──────┘
st ──────────────────────┘└─
395 refine ⟨_, _, rfl, append_inj this _⟩,
id └─┘ └────────┘ └──┘
src └─────┘ └────┘└─┘└┘└────────┘┴ └─┘
typ └─────┘ └────┘└─┘└┘└────────┘┴└──┘└─┘
doc └─────┘ └────┘ └┘ ┴ └─┘
txt └─────┘ └────┘ └┘ ┴ └─┘
par └─────┘ └────┘ └┘ ┴ └─┘
pid ┴ └────┘ └┘ ┴ └─┘
st ──────────────────────────────────────┘└─
396 rw [length_map, length_take, min_eq_left],
id └────────┘ └─────────┘ └─────────┘
src └──┘└────────┘└┘└─────────┘└┘└─────────┘┴
typ └──┘└────────┘└┘└─────────┘└┘└─────────┘┴
doc └──┘ └┘ └┘ ┴
txt └──┘ └┘ └┘ ┴
par └──┘ └┘ └┘ ┴
pid └┘ └┘ └┘ ┴
st ───────────────┘└───────────┘└───────────┘└──
397 rw [← length_map f l, h, length_append],
id └────────┘ ┴ ┴ ┴ └───────────┘
src └────┘└────────┘┴ ┴ └┘ └┘└───────────┘┴
typ └────┘└────────┘┴┴┴┴└┘┴└┘└───────────┘┴
doc └────┘ ┴ ┴ └┘ └┘ ┴
txt └────┘ ┴ ┴ └┘ └┘ ┴
par └────┘ ┴ ┴ └┘ └┘ ┴
pid └──┘ ┴ ┴ └┘ └┘ ┴
st ─────────────────────┘└─┘└─────────────┘└──
398 apply nat.le_add_right
id └──────────────┘
src └────┘└──────────────┘┴
typ └────┘└──────────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ────────────────────────┘
399 end
st └─┘
400
401 /- join -/
402
403 attribute [simp] join
id └──┘
src └──┘
typ └──┘
doc └──┘
404
405 theorem join_eq_nil : ∀ {L : list (list α)}, join L = [] ↔ ∀ l ∈ L, l = []
id ┴ └──┘ └──┘ ┴ └──┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘
src └──┘ └──┘ └──┘ ┴ └┘ ┴ ┴ └┘
typ ┴ └──┘ └──┘ ┴ └──┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘
406 | [] := iff_of_true rfl (forall_mem_nil _)
id └┘ └─────────┘ └─┘ └────────────┘
src └┘ └─────────┘ └─┘ └────────────┘
typ └┘ └─────────┘ └─┘ └────────────┘
407 | (l::L) := by simp only [join, append_eq_nil, join_eq_nil, forall_mem_cons]
id └┘ └──┘ └───────────┘ └─────────────┘
src └┘ └─────────┘└──┘└┘└───────────┘└┘ └┘└─────────────┘└─
typ └┘ └─────────┘└──┘└┘└───────────┘└┘└─────────┘└┘└─────────────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └──────────────────────────────────────────────────────────────
408
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
409 @[simp] theorem join_append (L₁ L₂ : list (list α)) : join (L₁ ++ L₂) = join L₁ ++ join L₂ :=
id └──┘ └──┘ ┴ └──┘ └┘ └┘ └┘ ┴ └──┘ └┘ └┘ └──┘ └┘
src └──┘ └──┘ └──┘ └┘ ┴ └──┘ └┘ └──┘
typ └──┘ └──┘ ┴ └──┘ └┘ └┘ └┘ ┴ └──┘ └┘ └┘ └──┘ └┘
doc └──┘
410 by induction L₁; [refl, simp only [*, join, cons_append, append_assoc]]
id └┘ ┴ └──┘ └─────────┘ └──────────┘
src └────────┘ ┴└──┘ └────────────┘└──┘└┘└─────────┘└┘└──────────┘┴
typ └────────┘└┘ ┴└──┘ └────────────┘└──┘└┘└─────────┘└┘└──────────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ ┴
st └───────────────────────────────────────────────────────────────────┘
411
412 lemma join_join (l : list (list (list α))) : l.join.join = (l.map join).join :=
id └──┘ └──┘ └──┘ ┴ ┴└────────┘ ┴ ┴└──┘ └──┘ └──┘
src └──┘ └──┘ └──┘ └────────┘ ┴ └──┘ └──┘ └──┘
typ └──┘ └──┘ └──┘ ┴ ┴└────────┘ ┴ ┴└──┘ └──┘ └──┘
413 by { induction l, simp, simp [l_ih] }
id ┴ └──┘
src └────────┘ └──┘ └────┘ └┘
typ └────────┘┴ └──┘ └────┘└──┘└┘
doc └────────┘ └──┘ └────┘ └┘
txt └────────┘ └──┘ └────┘ └┘
par └────────┘ └──┘ └────┘ └┘
pid ┴ ┴┴ ┴┴
st └────────────┘└────┘└────────────┘└┘
414
415 /- repeat -/
416
417 @[simp] theorem repeat_succ (a : α) (n) : repeat a (n + 1) = a :: repeat a n := rfl
id ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────┘ ┴ ┴ └─┘
src └────┘ ┴ ┴ └┘ └────┘ └─┘
typ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────┘ ┴ ┴ └─┘
doc └──┘
418
419 theorem eq_of_mem_repeat {a b : α} : ∀ {n}, b ∈ repeat a n → b = a
id ┴ ┴┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ ┴
typ ┴ ┴┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
420 | (n+1) h := or.elim h id $ @eq_of_mem_repeat _
id ┴ ┴ └─────┘ └┘ └──────────────┘
src ┴ └─────┘ └┘
typ ┴ ┴ └─────┘ └┘ └──────────────┘
421
422 theorem eq_repeat_of_mem {a : α} : ∀ {l : list α}, (∀ b ∈ l, b = a) → l = repeat a l.length
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘
src └──┘ ┴ ┴ └────┘ └─────┘
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘
423 | [] H := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
424 | (b::l) H := by cases forall_mem_cons.1 H with H₁ H₂;
id └┘ └─────────────┘ ┴
src └┘ └────┘└─────────────┘└─┘ └─────────┘
typ └┘ └────┘└─────────────┘└─┘┴└─────────┘
doc └────┘ └─┘ └─────────┘
txt └────┘ └─┘ └─────────┘
par └────┘ └─┘ └─────────┘
pid ┴ └─┘ └─────────┘
st └──────────────────────────────────────
425 unfold length repeat; congr; [exact H₁, exact eq_repeat_of_mem H₂]
id ┴ └┘ └──────────────┘ └┘
src └──────────────────┘ └───┘ ┴└────┘ └────┘ ┴
typ └──────────────────┘ └───┘ ┴└────┘└┘ └────┘└──────────────┘┴└┘
doc └──────────────────┘ └────┘ └────┘ ┴
txt └──────────────────┘ └───┘ └────┘ └────┘ ┴
par └──────────────────┘ └───┘ └────┘ └────┘ ┴
pid └────────────┘ ┴ ┴ ┴
st ───────────────────────────────────────────────────────────────────┘
426
427 theorem eq_repeat' {a : α} {l : list α} : l = repeat a l.length ↔ ∀ b ∈ l, b = a :=
id ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ └─────┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴ ┴
428 ⟨λ h, h.symm ▸ λ b, eq_of_mem_repeat, eq_repeat_of_mem⟩
id ┴ ┴└───┘ ┴ ┴ └──────────────┘ └──────────────┘
src └───┘ ┴ └──────────────┘ └──────────────┘
typ ┴ ┴└───┘ ┴ ┴ └──────────────┘ └──────────────┘
429
430 theorem eq_repeat {a : α} {n} {l : list α} : l = repeat a n ↔ length l = n ∧ ∀ b ∈ l, b = a :=
id ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴ └────┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
431 ⟨λ h, h.symm ▸ ⟨length_repeat _ _, λ b, eq_of_mem_repeat⟩,
id ┴ ┴└───┘ ┴ └───────────┘ ┴ └──────────────┘
src └───┘ ┴ └───────────┘ └──────────────┘
typ ┴ ┴└───┘ ┴ └───────────┘ ┴ └──────────────┘
432 λ ⟨e, al⟩, e ▸ eq_repeat_of_mem al⟩
id ┴┴ └┘ ┴ └──────────────┘
src ┴ └──────────────┘
typ ┴┴ └┘ ┴ └──────────────┘
433
434 theorem repeat_add (a : α) (m n) : repeat a (m + n) = repeat a m ++ repeat a n :=
id ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ └────┘ ┴ ┴
src └────┘ ┴ ┴ └────┘ └┘ └────┘
typ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ └────┘ ┴ ┴
435 by induction m; simp only [*, zero_add, succ_add, repeat]; split; refl
id ┴ └──────┘ └──────┘ └────┘
src └────────┘ └────────────┘└──────┘└┘└──────┘└┘└────┘┴ └───┘ └────
typ └────────┘┴ └────────────┘└──────┘└┘└──────┘└┘└────┘┴ └───┘ └────
doc └────────┘ └────────────┘ └┘ └┘ ┴ └───┘ └────
txt └────────┘ └────────────┘ └┘ └┘ ┴ └───┘ └────
par └────────┘ └────────────┘ └┘ └┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ └┘ └┘ ┴ └
st └────────────────────────────────────────────────────────────────────
436
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
437 theorem repeat_subset_singleton (a : α) (n) : repeat a n ⊆ [a] :=
id ┴ └────┘ ┴ ┴ ┴ ┴┴┴
src └────┘ ┴ ┴ ┴
typ ┴ └────┘ ┴ ┴ ┴ ┴┴┴
438 λ b h, mem_singleton.2 (eq_of_mem_repeat h)
id ┴ ┴ └───────────┘┴ └──────────────┘ ┴
src └───────────┘┴ └──────────────┘
typ ┴ ┴ └───────────┘┴ └──────────────┘ ┴
439
440 @[simp] theorem map_const (l : list α) (b : β) : map (function.const α b) l = repeat b l.length :=
id └──┘ ┴ ┴ └─┘ └────────────┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘
src └──┘ └─┘ └────────────┘ ┴ └────┘ └─────┘
typ └──┘ ┴ ┴ └─┘ └────────────┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘
doc └──┘
441 by induction l; [refl, simp only [*, map]]; split; refl
id ┴ ┴ └─┘
src └────────┘ ┴└──┘ └────────────┘└─┘┴ └───┘ └────
typ └────────┘┴ ┴└──┘ └────────────┘└─┘┴ └───┘ └────
doc └────────┘ └──┘ └────────────┘ ┴ └───┘ └────
txt └────────┘ └──┘ └────────────┘ ┴ └───┘ └────
par └────────┘ └──┘ └────────────┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ ┴ └
st └─────────────────────────────────────────────────────
442
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
443 theorem eq_of_mem_map_const {b₁ b₂ : β} {l : list α} (h : b₁ ∈ map (function.const α b₂) l) : b₁ = b₂ :=
id ┴ └──┘ ┴ └┘ ┴ └─┘ └────────────┘ ┴ └┘ ┴ └┘ ┴ └┘
src └──┘ ┴ └─┘ └────────────┘ ┴
typ ┴ └──┘ ┴ └┘ ┴ └─┘ └────────────┘ ┴ └┘ ┴ └┘ ┴ └┘
444 by rw map_const at h; exact eq_of_mem_repeat h
id └───────┘ └──────────────┘ ┴
src └─┘└───────┘└───┘ └────┘└──────────────┘┴ └
typ └─┘└───────┘└───┘ └────┘└──────────────┘┴┴└
doc └─┘ └───┘ └────┘ ┴ └
txt └─┘ └───┘ └────┘ ┴ └
par └─┘ └───┘ └────┘ ┴ └
pid ┴ └───┘ ┴ ┴ └
st └────────────────────────────────────────────
445
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
446 @[simp] theorem map_repeat (f : α → β) (a : α) (n) : map f (repeat a n) = repeat (f a) n :=
id ┴ ┴ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴
src └─┘ └────┘ ┴ └────┘
typ ┴ ┴ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴
doc └──┘
447 by induction n; [refl, simp only [*, repeat, map]]; split; refl
id ┴ ┴ └────┘ └─┘
src └────────┘ ┴└──┘ └────────────┘└────┘└┘└─┘┴ └───┘ └────
typ └────────┘┴ ┴└──┘ └────────────┘└────┘└┘└─┘┴ └───┘ └────
doc └────────┘ └──┘ └────────────┘ └┘ ┴ └───┘ └────
txt └────────┘ └──┘ └────────────┘ └┘ ┴ └───┘ └────
par └────────┘ └──┘ └────────────┘ └┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ └┘ ┴ └
st └─────────────────────────────────────────────────────────────
448
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
449 @[simp] theorem tail_repeat (a : α) (n) : tail (repeat a n) = repeat a n.pred :=
id ┴ └──┘ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴└───┘
src └──┘ └────┘ ┴ └────┘ └───┘
typ ┴ └──┘ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴└───┘
doc └──┘
450 by cases n; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
451
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
452 @[simp] theorem join_repeat_nil (n : ℕ) : join (repeat [] n) = @nil α :=
id ┴ └──┘ └────┘ └┘ ┴ ┴ └─┘ ┴
src ┴ └──┘ └────┘ └┘ ┴ └─┘
typ ┴ └──┘ └────┘ └┘ ┴ ┴ └─┘ ┴
doc └──┘
453 by induction n; [refl, simp only [*, repeat, join, append_nil]]
id ┴ ┴ └────┘ └──┘ └────────┘
src └────────┘ ┴└──┘ └────────────┘└────┘└┘└──┘└┘└────────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└────┘└┘└──┘└┘└────────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ ┴
st └───────────────────────────────────────────────────────────┘
454
455 /- bind -/
456
457 @[simp] theorem bind_eq_bind {α β} (f : α → list β) (l : list α) :
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
doc └──┘
458 l >>= f = l.bind f := rfl
id ┴ └─┘ ┴ ┴ ┴└───┘ ┴ └─┘
src └─┘ ┴ └───┘ └─┘
typ ┴ └─┘ ┴ ┴ ┴└───┘ ┴ └─┘
459
460 @[simp] theorem bind_append (f : α → list β) (l₁ l₂ : list α) :
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
doc └──┘
461 (l₁ ++ l₂).bind f = l₁.bind f ++ l₂.bind f :=
id └┘ └┘ └┘ └──┘ ┴ ┴ └┘└───┘ ┴ └┘ └┘└───┘ ┴
src └┘ └──┘ ┴ └───┘ └┘ └───┘
typ └┘ └┘ └┘ └──┘ ┴ ┴ └┘└───┘ ┴ └┘ └┘└───┘ ┴
462 append_bind _ _ _
id └─────────┘
src └─────────┘
typ └─────────┘
463
464 /- concat -/
465
466 @[simp] theorem concat_nil (a : α) : concat [] a = [a] := rfl
id ┴ └────┘ └┘ ┴ ┴ ┴┴┴ └─┘
src └────┘ └┘ ┴ ┴ ┴ └─┘
typ ┴ └────┘ └┘ ┴ ┴ ┴┴┴ └─┘
doc └──┘ └────┘
467
468 @[simp] theorem concat_cons (a b : α) (l : list α) : concat (a :: l) b = a :: concat l b := rfl
id ┴ └──┘ ┴ └────┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └────┘ ┴ ┴ └─┘
src └──┘ └────┘ └┘ ┴ └┘ └────┘ └─┘
typ ┴ └──┘ ┴ └────┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └────┘ ┴ ┴ └─┘
doc └──┘ └────┘ └────┘
469
470 @[simp] theorem concat_ne_nil (a : α) (l : list α) : concat l a ≠ [] :=
id ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └┘
src └──┘ └────┘ ┴ └┘
typ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └┘
doc └──┘ └────┘
471 by induction l; intro h; contradiction
id ┴
src └────────┘ └─────┘ └─────────────
typ └────────┘┴ └─────┘ └─────────────
doc └────────┘ └─────┘ └─────────────
txt └────────┘ └─────┘ └─────────────
par └────────┘ └─────┘ └─────────────
pid ┴ └┘ └
st └────────────────────────────────────
472
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
473 @[simp] theorem concat_append (a : α) (l₁ l₂ : list α) : concat l₁ a ++ l₂ = l₁ ++ a :: l₂ :=
id ┴ └──┘ ┴ └────┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘
src └──┘ └────┘ └┘ ┴ └┘ └┘
typ ┴ └──┘ ┴ └────┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘
doc └──┘ └────┘
474 by induction l₁; simp only [*, cons_append, concat]; split; refl
id └┘ └─────────┘ └────┘
src └────────┘ └────────────┘└─────────┘└┘└────┘┴ └───┘ └────
typ └────────┘└┘ └────────────┘└─────────┘└┘└────┘┴ └───┘ └────
doc └────────┘ └────────────┘ └┘└────┘┴ └───┘ └────
txt └────────┘ └────────────┘ └┘ ┴ └───┘ └────
par └────────┘ └────────────┘ └┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ └┘ ┴ └
st └──────────────────────────────────────────────────────────────
475
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
476 @[simp] theorem concat_eq_append (a : α) (l : list α) : concat l a = l ++ [a] :=
id ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴┴┴
src └──┘ └────┘ ┴ └┘ ┴ ┴
typ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴┴┴
doc └──┘ └────┘
477 by induction l; simp only [*, concat]; split; refl
id ┴ └────┘
src └────────┘ └────────────┘└────┘┴ └───┘ └────
typ └────────┘┴ └────────────┘└────┘┴ └───┘ └────
doc └────────┘ └────────────┘└────┘┴ └───┘ └────
txt └────────┘ └────────────┘ ┴ └───┘ └────
par └────────┘ └────────────┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ ┴ └
st └────────────────────────────────────────────────
478
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
479 @[simp] theorem length_concat (a : α) (l : list α) : length (concat l a) = succ (length l) :=
id ┴ └──┘ ┴ └────┘ └────┘ ┴ ┴ ┴ └──┘ └────┘ ┴
src └──┘ └────┘ └────┘ ┴ └──┘ └────┘
typ ┴ └──┘ ┴ └────┘ └────┘ ┴ ┴ ┴ └──┘ └────┘ ┴
doc └──┘ └────┘
480 by simp only [concat_eq_append, length_append, length]
id └──────────────┘ └───────────┘ └────┘
src └─────────┘└──────────────┘└┘└───────────┘└┘└────┘└─
typ └─────────┘└──────────────┘└┘└───────────┘└┘└────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────
481
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
482 theorem append_concat (a : α) (l₁ l₂ : list α) : l₁ ++ concat l₂ a = concat (l₁ ++ l₂) a :=
id ┴ └──┘ ┴ └┘ └┘ └────┘ └┘ ┴ ┴ └────┘ └┘ └┘ └┘ ┴
src └──┘ └┘ └────┘ ┴ └────┘ └┘
typ ┴ └──┘ ┴ └┘ └┘ └────┘ └┘ ┴ ┴ └────┘ └┘ └┘ └┘ ┴
doc └────┘ └────┘
483 by induction l₂ with b l₂ ih; simp only [concat_eq_append, nil_append, cons_append, append_assoc]
id └┘ └──────────────┘ └────────┘ └─────────┘ └──────────┘
src └────────┘ └───────────┘ └─────────┘└──────────────┘└┘└────────┘└┘└─────────┘└┘└──────────┘└─
typ └────────┘└┘└───────────┘ └─────────┘└──────────────┘└┘└────────┘└┘└─────────┘└┘└──────────┘└─
doc └────────┘ └───────────┘ └─────────┘ └┘ └┘ └┘ └─
txt └────────┘ └───────────┘ └─────────┘ └┘ └┘ └┘ └─
par └────────┘ └───────────┘ └─────────┘ └┘ └┘ └┘ └─
pid ┴ ┴└──────────┘ ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────────────────────────────────────────────────────
484
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
485 /- reverse -/
src ──────────────
typ ──────────────
doc ──────────────
txt ──────────────
par ──────────────
pid ──────────────
st ──────────────
486
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
487 @[simp] theorem reverse_nil : reverse (@nil α) = [] := rfl
id └─────┘ └─┘ ┴ ┴ └┘ └─┘
src └─────┘ └─┘ ┴ └┘ └─┘
typ └─────┘ └─┘ ┴ ┴ └┘ └─┘
doc └──┘
488
489 local attribute [simp] reverse_core
id └──────────┘
src └──────────┘
typ └──────────┘
doc └──┘
490
491 @[simp] theorem reverse_cons (a : α) (l : list α) : reverse (a::l) = reverse l ++ [a] :=
id ┴ └──┘ ┴ └─────┘ ┴└┘┴ ┴ └─────┘ ┴ └┘ ┴┴┴
src └──┘ └─────┘ └┘ ┴ └─────┘ └┘ ┴ ┴
typ ┴ └──┘ ┴ └─────┘ ┴└┘┴ ┴ └─────┘ ┴ └┘ ┴┴┴
doc └──┘
492 have aux : ∀ l₁ l₂, reverse_core l₁ l₂ ++ [a] = reverse_core l₁ (l₂ ++ [a]),
id └┘ └┘ └──────────┘ └┘ └┘ └┘ ┴┴┴ ┴ └──────────┘ └┘ └┘ └┘ ┴┴┴
src └──────────┘ └┘ ┴ ┴ ┴ └──────────┘ └┘ ┴ ┴
typ └┘ └┘ └──────────┘ └┘ └┘ └┘ ┴┴┴ ┴ └──────────┘ └┘ └┘ └┘ ┴┴┴
493 by intro l₁; induction l₁; intros; [refl, simp only [*, reverse_core, cons_append]],
id └┘ ┴ └──────────┘ └─────────┘
src └──────┘ └────────┘ └────┘ ┴└──┘ └────────────┘└──────────┘└┘└─────────┘┴
typ └──────┘ └────────┘└┘ └────┘ ┴└──┘ └────────────┘└──────────┘└┘└─────────┘┴
doc └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
txt └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
par └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
pid └─┘ ┴ ┴└──┘└───┘ └┘ ┴
st └───────────────────────────────────────────────────────────────────────────────┘
494 (aux l nil).symm
id └─┘ ┴ └─┘ └──┘
src └─┘ └──┘
typ └─┘ ┴ └─┘ └──┘
495
496 theorem reverse_core_eq (l₁ l₂ : list α) : reverse_core l₁ l₂ = reverse l₁ ++ l₂ :=
id └──┘ ┴ └──────────┘ └┘ └┘ ┴ └─────┘ └┘ └┘ └┘
src └──┘ └──────────┘ ┴ └─────┘ └┘
typ └──┘ ┴ └──────────┘ └┘ └┘ ┴ └─────┘ └┘ └┘ └┘
497 by induction l₁ generalizing l₂; [refl, simp only [*, reverse_core, reverse_cons, append_assoc]]; refl
id └┘ ┴ └──────────┘ └──────────┘ └──────────┘
src └────────┘ └──────────────┘ ┴└──┘ └────────────┘└──────────┘└┘└──────────┘└┘└──────────┘┴ └────
typ └────────┘└┘└──────────────┘ ┴└──┘ └────────────┘└──────────┘└┘└──────────┘└┘└──────────┘┴ └────
doc └────────┘ └──────────────┘ └──┘ └────────────┘ └┘ └┘ ┴ └────
txt └────────┘ └──────────────┘ └──┘ └────────────┘ └┘ └┘ ┴ └────
par └────────┘ └──────────────┘ └──┘ └────────────┘ └┘ └┘ ┴ └────
pid ┴ ┴└─────────────┘ ┴└──┘└───┘ └┘ └┘ ┴ └
st └────────────────────────────────────────────────────────────────────────────────────────────────────
498
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
499 theorem reverse_cons' (a : α) (l : list α) : reverse (a::l) = concat (reverse l) a :=
id ┴ └──┘ ┴ └─────┘ ┴└┘┴ ┴ └────┘ └─────┘ ┴ ┴
src └──┘ └─────┘ └┘ ┴ └────┘ └─────┘
typ ┴ └──┘ ┴ └─────┘ ┴└┘┴ ┴ └────┘ └─────┘ ┴ ┴
doc └────┘
500 by simp only [reverse_cons, concat_eq_append]
id └──────────┘ └──────────────┘
src └─────────┘└──────────┘└┘└──────────────┘└─
typ └─────────┘└──────────┘└┘└──────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └───────────────────────────────────────────
501
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
502 @[simp] theorem reverse_singleton (a : α) : reverse [a] = [a] := rfl
id ┴ └─────┘ ┴┴┴ ┴ ┴┴┴ └─┘
src └─────┘ ┴ ┴ ┴ ┴ ┴ └─┘
typ ┴ └─────┘ ┴┴┴ ┴ ┴┴┴ └─┘
doc └──┘
503
504 @[simp] theorem reverse_append (s t : list α) : reverse (s ++ t) = (reverse t) ++ (reverse s) :=
id └──┘ ┴ └─────┘ ┴ └┘ ┴ ┴ └─────┘ ┴ └┘ └─────┘ ┴
src └──┘ └─────┘ └┘ ┴ └─────┘ └┘ └─────┘
typ └──┘ ┴ └─────┘ ┴ └┘ ┴ ┴ └─────┘ ┴ └┘ └─────┘ ┴
doc └──┘
505 by induction s; [rw [nil_append, reverse_nil, append_nil],
id ┴ ┴ └────────┘ └─────────┘ └────────┘
src └────────┘ ┴└──┘└────────┘└┘└─────────┘└┘└────────┘┴
typ └────────┘┴ ┴└──┘└────────┘└┘└─────────┘└┘└────────┘┴
doc └────────┘ └──┘ └┘ └┘ ┴
txt └────────┘ └──┘ └┘ └┘ ┴
par └────────┘ └──┘ └┘ └┘ ┴
pid ┴ └┘ └┘ └┘ ┴
st └─────────────────┘└────────┘└───────────┘└──────────┘┴└─
506 simp only [*, cons_append, reverse_cons, append_assoc]]
id └─────────┘ └──────────┘ └──────────┘
src └────────────┘└─────────┘└┘└──────────┘└┘└──────────┘┴
typ └────────────┘└─────────┘└┘└──────────┘└┘└──────────┘┴
doc └────────────┘ └┘ └┘ ┴
txt └────────────┘ └┘ └┘ ┴
par └────────────┘ └┘ └┘ ┴
pid ┴└──┘└───┘ └┘ └┘ ┴
st ──────────────────────────────────────────────────────┘
507
508 @[simp] theorem reverse_reverse (l : list α) : reverse (reverse l) = l :=
id └──┘ ┴ └─────┘ └─────┘ ┴ ┴ ┴
src └──┘ └─────┘ └─────┘ ┴
typ └──┘ ┴ └─────┘ └─────┘ ┴ ┴ ┴
doc └──┘
509 by induction l; [refl, simp only [*, reverse_cons, reverse_append]]; refl
id ┴ ┴ └──────────┘ └────────────┘
src └────────┘ ┴└──┘ └────────────┘└──────────┘└┘└────────────┘┴ └────
typ └────────┘┴ ┴└──┘ └────────────┘└──────────┘└┘└────────────┘┴ └────
doc └────────┘ └──┘ └────────────┘ └┘ ┴ └────
txt └────────┘ └──┘ └────────────┘ └┘ ┴ └────
par └────────┘ └──┘ └────────────┘ └┘ ┴ └────
pid ┴ ┴└──┘└───┘ └┘ ┴ └
st └───────────────────────────────────────────────────────────────────────
510
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
511 theorem reverse_injective : injective (@reverse α) :=
id └───────┘ └─────┘ ┴
src └───────┘ └─────┘
typ └───────┘ └─────┘ ┴
512 injective_of_left_inverse reverse_reverse
id └───────────────────────┘ └─────────────┘
src └───────────────────────┘ └─────────────┘
typ └───────────────────────┘ └─────────────┘
513
514 @[simp] theorem reverse_inj {l₁ l₂ : list α} : reverse l₁ = reverse l₂ ↔ l₁ = l₂ :=
id └──┘ ┴ └─────┘ └┘ ┴ └─────┘ └┘ ┴ └┘ ┴ └┘
src └──┘ └─────┘ ┴ └─────┘ ┴ ┴
typ └──┘ ┴ └─────┘ └┘ ┴ └─────┘ └┘ ┴ └┘ ┴ └┘
doc └──┘
515 reverse_injective.eq_iff
id └───────────────┘└─────┘
src └───────────────┘└─────┘
typ └───────────────┘└─────┘
516
517 @[simp] theorem reverse_eq_nil {l : list α} : reverse l = [] ↔ l = [] :=
id └──┘ ┴ └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ └─────┘ ┴ └┘ ┴ ┴ └┘
typ └──┘ ┴ └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
518 @reverse_inj _ l []
id └─────────┘ ┴ └┘
src └─────────┘ └┘
typ └─────────┘ ┴ └┘
519
520 theorem concat_eq_reverse_cons (a : α) (l : list α) : concat l a = reverse (a :: reverse l) :=
id ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └─────┘ ┴ └┘ └─────┘ ┴
src └──┘ └────┘ ┴ └─────┘ └┘ └─────┘
typ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └─────┘ ┴ └┘ └─────┘ ┴
doc └────┘
521 by simp only [concat_eq_append, reverse_cons, reverse_reverse]
id └──────────────┘ └──────────┘ └─────────────┘
src └─────────┘└──────────────┘└┘└──────────┘└┘└─────────────┘└─
typ └─────────┘└──────────────┘└┘└──────────┘└┘└─────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────
522
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
523 @[simp] theorem length_reverse (l : list α) : length (reverse l) = length l :=
id └──┘ ┴ └────┘ └─────┘ ┴ ┴ └────┘ ┴
src └──┘ └────┘ └─────┘ ┴ └────┘
typ └──┘ ┴ └────┘ └─────┘ ┴ ┴ └────┘ ┴
doc └──┘
524 by induction l; [refl, simp only [*, reverse_cons, length_append, length]]
id ┴ ┴ └──────────┘ └───────────┘ └────┘
src └────────┘ ┴└──┘ └────────────┘└──────────┘└┘└───────────┘└┘└────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└──────────┘└┘└───────────┘└┘└────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ ┴
st └──────────────────────────────────────────────────────────────────────┘
525
526 @[simp] theorem map_reverse (f : α → β) (l : list α) : map f (reverse l) = reverse (map f l) :=
id ┴ ┴ └──┘ ┴ └─┘ ┴ └─────┘ ┴ ┴ └─────┘ └─┘ ┴ ┴
src └──┘ └─┘ └─────┘ ┴ └─────┘ └─┘
typ ┴ ┴ └──┘ ┴ └─┘ ┴ └─────┘ ┴ ┴ └─────┘ └─┘ ┴ ┴
doc └──┘
527 by induction l; [refl, simp only [*, map, reverse_cons, map_append]]
id ┴ ┴ └─┘ └──────────┘ └────────┘
src └────────┘ ┴└──┘ └────────────┘└─┘└┘└──────────┘└┘└────────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└─┘└┘└──────────┘└┘└────────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ ┴
st └────────────────────────────────────────────────────────────────┘
528
529 theorem map_reverse_core (f : α → β) (l₁ l₂ : list α) :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
530 map f (reverse_core l₁ l₂) = reverse_core (map f l₁) (map f l₂) :=
id └─┘ ┴ └──────────┘ └┘ └┘ ┴ └──────────┘ └─┘ ┴ └┘ └─┘ ┴ └┘
src └─┘ └──────────┘ ┴ └──────────┘ └─┘ └─┘
typ └─┘ ┴ └──────────┘ └┘ └┘ ┴ └──────────┘ └─┘ ┴ └┘ └─┘ ┴ └┘
531 by simp only [reverse_core_eq, map_append, map_reverse]
id └─────────────┘ └────────┘ └─────────┘
src └─────────┘└─────────────┘└┘└────────┘└┘└─────────┘└─
typ └─────────┘└─────────────┘└┘└────────┘└┘└─────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────
532
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
533 @[simp] theorem mem_reverse {a : α} {l : list α} : a ∈ reverse l ↔ a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └─────┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘
534 by induction l; [refl, simp only [*, reverse_cons, mem_append, mem_singleton, mem_cons_iff, not_mem_nil, false_or, or_false, or_comm]]
id ┴ ┴ └──────────┘ └────────┘ └───────────┘ └──────────┘ └─────────┘ └──────┘ └──────┘ └─────┘
src └────────┘ ┴└──┘ └────────────┘└──────────┘└┘└────────┘└┘└───────────┘└┘└──────────┘└┘└─────────┘└┘└──────┘└┘└──────┘└┘└─────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└──────────┘└┘└────────┘└┘└───────────┘└┘└──────────┘└┘└─────────┘└┘└──────┘└┘└──────┘└┘└─────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
st └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
535
536 @[simp] theorem reverse_repeat (a : α) (n) : reverse (repeat a n) = repeat a n :=
id ┴ └─────┘ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
src └─────┘ └────┘ ┴ └────┘
typ ┴ └─────┘ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
doc └──┘
537 eq_repeat.2 ⟨by simp only [length_reverse, length_repeat], λ b h, eq_of_mem_repeat (mem_reverse.1 h)⟩
id └───────┘┴ └────────────┘ └───────────┘ ┴ ┴ └──────────────┘ └─────────┘┴ ┴
src └───────┘┴ └─────────┘└────────────┘└┘└───────────┘┴ └──────────────┘ └─────────┘┴
typ └───────┘┴ └─────────┘└────────────┘└┘└───────────┘┴ ┴ ┴ └──────────────┘ └─────────┘┴ ┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st └────────────────────────────────────────┘
538
539 @[elab_as_eliminator] def reverse_rec_on {C : list α → Sort*}
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └────────────────┘
540 (l : list α) (H0 : C [])
id └──┘ ┴ ┴ └┘
src └──┘ └┘
typ └──┘ ┴ ┴ └┘
541 (H1 : ∀ (l : list α) (a : α), C l → C (l ++ [a])) : C l :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴┴┴ ┴ ┴
src └──┘ └┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴┴┴ ┴ ┴
542 begin
st └─────
543 rw ← reverse_reverse l,
id └─────────────┘ ┴
src └───┘└─────────────┘┴
typ └───┘└─────────────┘┴┴
doc └───┘ ┴
txt └───┘ ┴
par └───┘ ┴
pid └─┘ ┴
st ───────────────────────┘└─
544 induction reverse l,
id └─────┘ ┴
src └────────┘└─────┘┴
typ └────────┘└─────┘┴┴
doc └────────┘ ┴
txt └────────┘ ┴
par └────────┘ ┴
pid ┴ ┴
st ────────────────────┘└─
545 { exact H0 },
id └┘
src └────┘ ┴
typ └────┘└┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───┘└───────┘└┘└
546 { rw reverse_cons, exact H1 _ _ ih }
id └──────────┘ └┘ └┘
src └─┘└──────────┘ └────┘ └───┘ ┴
typ └─┘└──────────┘ └────┘└┘└───┘└┘┴
doc └─┘ └────┘ └───┘ ┴
txt └─┘ └────┘ └───┘ ┴
par └─┘ └────┘ └───┘ ┴
pid ┴ ┴ └───┘ ┴
st ──────────────────┘└────────────────┘└─
547 end
st ──┘
548
549 /- last -/
550
551 @[simp] theorem last_cons {a : α} {l : list α} : ∀ (h₁ : a :: l ≠ nil) (h₂ : l ≠ nil), last (a :: l) h₁ = last l h₂ :=
id ┴ └──┘ ┴ ┴ └┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └──┘ ┴ └┘ ┴ └┘ ┴ └──┘ ┴ └┘
src └──┘ └┘ ┴ └─┘ ┴ └─┘ └──┘ └┘ ┴ └──┘
typ ┴ └──┘ ┴ ┴ └┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └──┘ ┴ └┘ ┴ └┘ ┴ └──┘ ┴ └┘
doc └──┘
552 by {induction l; intros, contradiction, reflexivity}
id ┴
src └────────┘ └────┘ └───────────┘ └─────────┘
typ └────────┘┴ └────┘ └───────────┘ └─────────┘
doc └────────┘ └────┘ └───────────┘ └─────────┘
txt └────────┘ └────┘ └───────────┘ └─────────┘
par └────────┘ └────┘ └───────────┘ └─────────┘
pid ┴
st └───────────────────┘└─────────────┘└───────────┘└┘
553
554 @[simp] theorem last_append {a : α} (l : list α) (h : l ++ [a] ≠ []) : last (l ++ [a]) h = a :=
id ┴ └──┘ ┴ ┴ └┘ ┴┴┴ ┴ └┘ └──┘ ┴ └┘ ┴┴┴ ┴ ┴ ┴
src └──┘ └┘ ┴ ┴ ┴ └┘ └──┘ └┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ └┘ ┴┴┴ ┴ └┘ └──┘ ┴ └┘ ┴┴┴ ┴ ┴ ┴
doc └──┘
555 by induction l; [refl, simp only [cons_append, last_cons _ (λ H, cons_ne_nil _ _ (append_eq_nil.1 H).2), *]]
id ┴ ┴ └─────────┘ └───────┘ └─────────┘ └───────────┘
src └────────┘ ┴└──┘ └─────────┘└─────────┘└┘└───────┘└─┘ └──┘└─────────┘└───┘ └───────────┘└─┘ └──────┘
typ └────────┘┴ ┴└──┘ └─────────┘└─────────┘└┘└───────┘└─┘ └──┘└─────────┘└───┘ └───────────┘└─┘ └──────┘
doc └────────┘ └──┘ └─────────┘ └┘ └─┘ └──┘ └───┘ └─┘ └──────┘
txt └────────┘ └──┘ └─────────┘ └┘ └─┘ └──┘ └───┘ └─┘ └──────┘
par └────────┘ └──┘ └─────────┘ └┘ └─┘ └──┘ └───┘ └─┘ └──────┘
pid ┴ ┴└──┘└┘ └┘ └─┘ └──┘ └───┘ └─┘ └──────┘
st └────────────────────────────────────────────────────────────────────────────────────────────────────────┘
556
557 theorem last_concat {a : α} (l : list α) (h : concat l a ≠ []) : last (concat l a) h = a :=
id ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └┘ └──┘ └────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └────┘ ┴ └┘ └──┘ └────┘ ┴
typ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └┘ └──┘ └────┘ ┴ ┴ ┴ ┴ ┴
doc └────┘ └────┘
558 by simp only [concat_eq_append, last_append]
id └──────────────┘ └─────────┘
src └─────────┘└──────────────┘└┘└─────────┘└─
typ └─────────┘└──────────────┘└┘└─────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └──────────────────────────────────────────
559
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
560 @[simp] theorem last_singleton (a : α) (h : [a] ≠ []) : last [a] h = a := rfl
id ┴ ┴┴┴ ┴ └┘ └──┘ ┴┴┴ ┴ ┴ ┴ └─┘
src ┴ ┴ ┴ └┘ └──┘ ┴ ┴ ┴ └─┘
typ ┴ ┴┴┴ ┴ └┘ └──┘ ┴┴┴ ┴ ┴ ┴ └─┘
doc └──┘
561
562 @[simp] theorem last_cons_cons (a₁ a₂ : α) (l : list α) (h : a₁::a₂::l ≠ []) :
id ┴ └──┘ ┴ └┘└┘└┘└┘┴ ┴ └┘
src └──┘ └┘ └┘ ┴ └┘
typ ┴ └──┘ ┴ └┘└┘└┘└┘┴ ┴ └┘
doc └──┘
563 last (a₁::a₂::l) h = last (a₂::l) (cons_ne_nil a₂ l) := rfl
id └──┘ └┘└┘└┘└┘┴ ┴ ┴ └──┘ └┘└┘┴ └─────────┘ └┘ ┴ └─┘
src └──┘ └┘ └┘ ┴ └──┘ └┘ └─────────┘ └─┘
typ └──┘ └┘└┘└┘└┘┴ ┴ ┴ └──┘ └┘└┘┴ └─────────┘ └┘ ┴ └─┘
564
565 theorem last_congr {l₁ l₂ : list α} (h₁ : l₁ ≠ []) (h₂ : l₂ ≠ []) (h₃ : l₁ = l₂) :
id └──┘ ┴ └┘ ┴ └┘ └┘ ┴ └┘ └┘ ┴ └┘
src └──┘ ┴ └┘ ┴ └┘ ┴
typ └──┘ ┴ └┘ ┴ └┘ └┘ ┴ └┘ └┘ ┴ └┘
566 last l₁ h₁ = last l₂ h₂ :=
id └──┘ └┘ └┘ ┴ └──┘ └┘ └┘
src └──┘ ┴ └──┘
typ └──┘ └┘ └┘ ┴ └──┘ └┘ └┘
567 by subst l₁
id └┘
src └────┘ └
typ └────┘└┘└
doc └────┘ └
txt └────┘ └
par └────┘ └
pid ┴ └
st └─────────
568
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
569 /- head(') and tail -/
src ───────────────────────
typ ───────────────────────
doc ───────────────────────
txt ───────────────────────
par ───────────────────────
pid ───────────────────────
st ───────────────────────
570
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
571 theorem head_eq_head' [inhabited α] (l : list α) : head l = (head' l).iget :=
id └───────┘ ┴ └──┘ ┴ └──┘ ┴ ┴ └───┘ ┴ └──┘
src └───────┘ └──┘ └──┘ ┴ └───┘ └──┘
typ └───────┘ ┴ └──┘ ┴ └──┘ ┴ ┴ └───┘ ┴ └──┘
doc └──┘
572 by cases l; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
573
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
574 @[simp] theorem head_cons [inhabited α] (a : α) (l : list α) : head (a::l) = a := rfl
id └───────┘ ┴ ┴ └──┘ ┴ └──┘ ┴└┘┴ ┴ ┴ └─┘
src └───────┘ └──┘ └──┘ └┘ ┴ └─┘
typ └───────┘ ┴ ┴ └──┘ ┴ └──┘ ┴└┘┴ ┴ ┴ └─┘
doc └──┘
575
576 @[simp] theorem tail_nil : tail (@nil α) = [] := rfl
id └──┘ └─┘ ┴ ┴ └┘ └─┘
src └──┘ └─┘ ┴ └┘ └─┘
typ └──┘ └─┘ ┴ ┴ └┘ └─┘
doc └──┘
577
578 @[simp] theorem tail_cons (a : α) (l : list α) : tail (a::l) = l := rfl
id ┴ └──┘ ┴ └──┘ ┴└┘┴ ┴ ┴ └─┘
src └──┘ └──┘ └┘ ┴ └─┘
typ ┴ └──┘ ┴ └──┘ ┴└┘┴ ┴ ┴ └─┘
doc └──┘
579
580 @[simp] theorem head_append [inhabited α] (t : list α) {s : list α} (h : s ≠ []) : head (s ++ t) = head s :=
id └───────┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘ └──┘ ┴ └┘ ┴ ┴ └──┘ ┴
src └───────┘ └──┘ └──┘ ┴ └┘ └──┘ └┘ ┴ └──┘
typ └───────┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘ └──┘ ┴ └┘ ┴ ┴ └──┘ ┴
doc └──┘
581 by {induction s, contradiction, refl}
id ┴
src └────────┘ └───────────┘ └──┘
typ └────────┘┴ └───────────┘ └──┘
doc └────────┘ └───────────┘ └──┘
txt └────────┘ └───────────┘ └──┘
par └────────┘ └───────────┘ └──┘
pid ┴
st └───────────┘└─────────────┘└────┘└┘
582
583 theorem cons_head_tail [inhabited α] {l : list α} (h : l ≠ []) : (head l)::(tail l) = l :=
id └───────┘ ┴ └──┘ ┴ ┴ ┴ └┘ └──┘ ┴ └┘ └──┘ ┴ ┴ ┴
src └───────┘ └──┘ ┴ └┘ └──┘ └┘ └──┘ ┴
typ └───────┘ ┴ └──┘ ┴ ┴ ┴ └┘ └──┘ ┴ └┘ └──┘ ┴ ┴ ┴
584 by {induction l, contradiction, refl}
id ┴
src └────────┘ └───────────┘ └──┘
typ └────────┘┴ └───────────┘ └──┘
doc └────────┘ └───────────┘ └──┘
txt └────────┘ └───────────┘ └──┘
par └────────┘ └───────────┘ └──┘
pid ┴
st └───────────┘└─────────────┘└────┘└┘
585
586 /- sublists -/
587
588 @[simp] theorem nil_sublist : Π (l : list α), [] <+ l
id ┴ └──┘ ┴ └┘ └┘ ┴
src └──┘ └┘ └┘
typ ┴ └──┘ ┴ └┘ └┘ ┴
doc └──┘
589 | [] := sublist.slnil
id └┘ └───────────┘
src └┘ └───────────┘
typ └┘ └───────────┘
590 | (a :: l) := sublist.cons _ _ a (nil_sublist l)
id ┴ └┘ ┴ └──────────┘ └─────────┘
src └┘ └──────────┘
typ ┴ └┘ ┴ └──────────┘ └─────────┘
591
592 @[refl, simp] theorem sublist.refl : Π (l : list α), l <+ l
id ┴ └──┘ ┴ ┴ └┘ ┴
src └──┘ └──┘ └┘
typ ┴ └──┘ ┴ ┴ └┘ ┴
doc └──┘ └──┘
593 | [] := sublist.slnil
id └┘ └───────────┘
src └┘ └───────────┘
typ └┘ └───────────┘
594 | (a :: l) := sublist.cons2 _ _ a (sublist.refl l)
id ┴ └┘ ┴ └───────────┘ └──────────┘
src └┘ └───────────┘
typ ┴ └┘ ┴ └───────────┘ └──────────┘
595
596 @[trans] theorem sublist.trans {l₁ l₂ l₃ : list α} (h₁ : l₁ <+ l₂) (h₂ : l₂ <+ l₃) : l₁ <+ l₃ :=
id └──┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘
src └───┘ └──┘ └┘ └┘ └┘
typ └──┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘
doc └───┘
597 sublist.rec_on h₂ (λ_ s, s)
id └────────────┘ └┘ ┴ ┴ ┴
src └────────────┘
typ └────────────┘ └┘ ┴ ┴ ┴
598 (λl₂ l₃ a h₂ IH l₁ h₁, sublist.cons _ _ _ (IH l₁ h₁))
id └┘ └┘ ┴ └┘ └┘ └┘ └┘ └──────────┘ └┘ └┘ └┘
src └──────────┘
typ └┘ └┘ ┴ └┘ └┘ └┘ └┘ └──────────┘ └┘ └┘ └┘
599 (λl₂ l₃ a h₂ IH l₁ h₁, @sublist.cases_on _ (λl₁ l₂', l₂' = a :: l₂ → l₁ <+ a :: l₃) _ _ h₁
id └┘ └┘ ┴ └┘ └┘ └┘ └┘ └──────────────┘ └┘ └─┘ └─┘ ┴ ┴ └┘ └┘ └┘ └┘ ┴ └┘ └┘ └┘
src └──────────────┘ ┴ └┘ └┘ └┘
typ └┘ └┘ ┴ └┘ └┘ └┘ └┘ └──────────────┘ └┘ └─┘ └─┘ ┴ ┴ └┘ └┘ └┘ └┘ ┴ └┘ └┘ └┘
600 (λ_, nil_sublist _)
id ┴ └─────────┘
src └─────────┘
typ ┴ └─────────┘
601 (λl₁ l₂' a' h₁' e, match a', l₂', e, h₁' with ._, ._, rfl, h₁ := sublist.cons _ _ _ (IH _ h₁) end)
id └┘ └─┘ └┘ └─┘ ┴ └┘ └─┘ ┴ └─┘ └─┘ └┘ └──────────┘ └┘
src └─┘ └──────────┘
typ └┘ └─┘ └┘ └─┘ ┴ └┘ └─┘ ┴ └─┘ └─┘ └┘ └──────────┘ └┘
602 (λl₁ l₂' a' h₁' e, match a', l₂', e, h₁' with ._, ._, rfl, h₁ := sublist.cons2 _ _ _ (IH _ h₁) end) rfl)
id └┘ └─┘ └┘ └─┘ ┴ └┘ └─┘ ┴ └─┘ └─┘ └┘ └───────────┘ └┘ └─┘
src └─┘ └───────────┘ └─┘
typ └┘ └─┘ └┘ └─┘ ┴ └┘ └─┘ ┴ └─┘ └─┘ └┘ └───────────┘ └┘ └─┘
603 l₁ h₁
id └┘ └┘
typ └┘ └┘
604
605 @[simp] theorem sublist_cons (a : α) (l : list α) : l <+ a::l :=
id ┴ └──┘ ┴ ┴ └┘ ┴└┘┴
src └──┘ └┘ └┘
typ ┴ └──┘ ┴ ┴ └┘ ┴└┘┴
doc └──┘
606 sublist.cons _ _ _ (sublist.refl l)
id └──────────┘ └──────────┘ ┴
src └──────────┘ └──────────┘
typ └──────────┘ └──────────┘ ┴
607
608 theorem sublist_of_cons_sublist {a : α} {l₁ l₂ : list α} : a::l₁ <+ l₂ → l₁ <+ l₂ :=
id ┴ └──┘ ┴ ┴└┘└┘ └┘ └┘ └┘ └┘ └┘
src └──┘ └┘ └┘ └┘
typ ┴ └──┘ ┴ ┴└┘└┘ └┘ └┘ └┘ └┘ └┘
609 sublist.trans (sublist_cons a l₁)
id └───────────┘ └──────────┘ ┴ └┘
src └───────────┘ └──────────┘
typ └───────────┘ └──────────┘ ┴ └┘
610
611 theorem cons_sublist_cons {l₁ l₂ : list α} (a : α) (s : l₁ <+ l₂) : a::l₁ <+ a::l₂ :=
id └──┘ ┴ ┴ └┘ └┘ └┘ ┴└┘└┘ └┘ ┴└┘└┘
src └──┘ └┘ └┘ └┘ └┘
typ └──┘ ┴ ┴ └┘ └┘ └┘ ┴└┘└┘ └┘ ┴└┘└┘
612 sublist.cons2 _ _ _ s
id └───────────┘ ┴
src └───────────┘
typ └───────────┘ ┴
613
614 @[simp] theorem sublist_append_left : Π (l₁ l₂ : list α), l₁ <+ l₁++l₂
id ┴ └──┘ ┴ └┘ └┘ └┘└┘└┘
src └──┘ └┘ └┘
typ ┴ └──┘ ┴ └┘ └┘ └┘└┘└┘
doc └──┘
615 | [] l₂ := nil_sublist _
id └┘ └─────────┘
src └┘ └─────────┘
typ └┘ └─────────┘
616 | (a::l₁) l₂ := cons_sublist_cons _ (sublist_append_left l₁ l₂)
id └┘└┘ └┘ └───────────────┘ └─────────────────┘
src └┘ └───────────────┘
typ └┘└┘ └┘ └───────────────┘ └─────────────────┘
617
618 @[simp] theorem sublist_append_right : Π (l₁ l₂ : list α), l₂ <+ l₁++l₂
id ┴ └──┘ ┴ └┘ └┘ └┘└┘└┘
src └──┘ └┘ └┘
typ ┴ └──┘ ┴ └┘ └┘ └┘└┘└┘
doc └──┘
619 | [] l₂ := sublist.refl _
id └┘ └──────────┘
src └┘ └──────────┘
typ └┘ └──────────┘
620 | (a::l₁) l₂ := sublist.cons _ _ _ (sublist_append_right l₁ l₂)
id └┘└┘ └┘ └──────────┘ └──────────────────┘
src └┘ └──────────┘
typ └┘└┘ └┘ └──────────┘ └──────────────────┘
621
622 theorem sublist_cons_of_sublist (a : α) {l₁ l₂ : list α} : l₁ <+ l₂ → l₁ <+ a::l₂ :=
id ┴ └──┘ ┴ └┘ └┘ └┘ └┘ └┘ ┴└┘└┘
src └──┘ └┘ └┘ └┘
typ ┴ └──┘ ┴ └┘ └┘ └┘ └┘ └┘ ┴└┘└┘
623 sublist.cons _ _ _
id └──────────┘
src └──────────┘
typ └──────────┘
624
625 theorem sublist_append_of_sublist_left {l l₁ l₂ : list α} (s : l <+ l₁) : l <+ l₁++l₂ :=
id └──┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘└┘└┘
src └──┘ └┘ └┘ └┘
typ └──┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘└┘└┘
626 s.trans $ sublist_append_left _ _
id ┴└────┘ └─────────────────┘
src └────┘ └─────────────────┘
typ ┴└────┘ └─────────────────┘
627
628 theorem sublist_append_of_sublist_right {l l₁ l₂ : list α} (s : l <+ l₂) : l <+ l₁++l₂ :=
id └──┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘└┘└┘
src └──┘ └┘ └┘ └┘
typ └──┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘└┘└┘
629 s.trans $ sublist_append_right _ _
id ┴└────┘ └──────────────────┘
src └────┘ └──────────────────┘
typ ┴└────┘ └──────────────────┘
630
631 theorem sublist_of_cons_sublist_cons {l₁ l₂ : list α} : ∀ {a : α}, a::l₁ <+ a::l₂ → l₁ <+ l₂
id └──┘ ┴ ┴ ┴ ┴└┘└┘ └┘ ┴└┘└┘ └┘ └┘ └┘
src └──┘ └┘ └┘ └┘ └┘
typ └──┘ ┴ ┴ ┴ ┴└┘└┘ └┘ ┴└┘└┘ └┘ └┘ └┘
632 | ._ (sublist.cons ._ ._ a s) := sublist_of_cons_sublist s
id └──────────┘ ┴ └─────────────────────┘
src └──────────┘ └─────────────────────┘
typ └──────────┘ ┴ └─────────────────────┘
633 | ._ (sublist.cons2 ._ ._ a s) := s
id └───────────┘ ┴
src └───────────┘
typ └───────────┘ ┴
634
635 theorem cons_sublist_cons_iff {l₁ l₂ : list α} {a : α} : a::l₁ <+ a::l₂ ↔ l₁ <+ l₂ :=
id └──┘ ┴ ┴ ┴└┘└┘ └┘ ┴└┘└┘ ┴ └┘ └┘ └┘
src └──┘ └┘ └┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ ┴└┘└┘ └┘ ┴└┘└┘ ┴ └┘ └┘ └┘
636 ⟨sublist_of_cons_sublist_cons, cons_sublist_cons _⟩
id └──────────────────────────┘ └───────────────┘
src └──────────────────────────┘ └───────────────┘
typ └──────────────────────────┘ └───────────────┘
637
638 @[simp] theorem append_sublist_append_left {l₁ l₂ : list α} : ∀ l, l++l₁ <+ l++l₂ ↔ l₁ <+ l₂
id └──┘ ┴ ┴ ┴└┘└┘ └┘ ┴└┘└┘ ┴ └┘ └┘ └┘
src └──┘ └┘ └┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ ┴└┘└┘ └┘ ┴└┘└┘ ┴ └┘ └┘ └┘
doc └──┘
639 | [] := iff.rfl
id └┘ └─────┘
src └┘ └─────┘
typ └┘ └─────┘
640 | (a::l) := cons_sublist_cons_iff.trans (append_sublist_append_left l)
id └┘┴ └───────────────────┘└────┘ └────────────────────────┘
src └┘ └───────────────────┘└────┘
typ └┘┴ └───────────────────┘└────┘ └────────────────────────┘
641
642 theorem append_sublist_append_of_sublist_right {l₁ l₂ : list α} (h : l₁ <+ l₂) (l) : l₁++l <+ l₂++l :=
id └──┘ ┴ └┘ └┘ └┘ └┘└┘┴ └┘ └┘└┘┴
src └──┘ └┘ └┘ └┘ └┘
typ └──┘ ┴ └┘ └┘ └┘ └┘└┘┴ └┘ └┘└┘┴
643 begin
st └─────
644 induction h with _ _ a _ ih _ _ a _ ih,
id ┴
src └────────┘ └─────────────────────────┘
typ └────────┘┴└─────────────────────────┘
doc └────────┘ └─────────────────────────┘
txt └────────┘ └─────────────────────────┘
par └────────┘ └─────────────────────────┘
pid ┴ ┴└────────────────────────┘
st ───────────────────────────────────────┘└─
645 { refl },
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st ───┘└───┘└┘└
646 { apply sublist_cons_of_sublist a ih },
id └─────────────────────┘ ┴ └┘
src └────┘└─────────────────────┘┴ ┴ ┴
typ └────┘└─────────────────────┘┴┴┴└┘┴
doc └────┘ ┴ ┴ ┴
txt └────┘ ┴ ┴ ┴
par └────┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ───┘└─────────────────────────────────┘└┘└
647 { apply cons_sublist_cons a ih }
id └───────────────┘ ┴ └┘
src └────┘└───────────────┘┴ ┴ ┴
typ └────┘└───────────────┘┴┴┴└┘┴
doc └────┘ ┴ ┴ ┴
txt └────┘ ┴ ┴ ┴
par └────┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ────────────────────────────────┘└─
648 end
st ──┘
649
650 theorem sublist_or_mem_of_sublist {l l₁ l₂ : list α} {a : α} (h : l <+ l₁ ++ a::l₂) : l <+ l₁ ++ l₂ ∨ a ∈ l :=
id └──┘ ┴ ┴ ┴ └┘ └┘ └┘ ┴└┘└┘ ┴ └┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴
src └──┘ └┘ └┘ └┘ └┘ └┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ └┘ └┘ └┘ ┴└┘└┘ ┴ └┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴
651 begin
st └─────
652 induction l₁ with b l₁ IH generalizing l,
id └┘
src └────────┘ └──────────────────────────┘
typ └────────┘└┘└──────────────────────────┘
doc └────────┘ └──────────────────────────┘
txt └────────┘ └──────────────────────────┘
par └────────┘ └──────────────────────────┘
pid ┴ ┴└──────────┘└─────────────┘
st ─────────────────────────────────────────┘└─
653 { cases h, { left, exact ‹l <+ l₂› }, { right, apply mem_cons_self } },
id ┴ ┴┴ └┘ └┘┴ └───────────┘
src └────┘ └──┘ └────┘┴ ┴└┘┴ ┴┴ └───┘ └────┘└───────────┘┴
typ └────┘┴ └──┘ └────┘┴┴┴└┘┴└┘┴┴ └───┘ └────┘└───────────┘┴
doc └────┘ └──┘ └────┘┴ ┴ ┴ ┴┴ └───┘ └────┘ ┴
txt └────┘ └──┘ └────┘ ┴ ┴ ┴ └───┘ └────┘ ┴
par └────┘ └──┘ └────┘ ┴ ┴ ┴ └───┘ └────┘ ┴
pid ┴ ┴ ┴ ┴ ┴ ┴ ┴
st ───┘└─────┘└──┘└──┘└────────────────┘└┘└──────┘└────────────────────┘└──┘└
654 { cases h with _ _ _ h _ _ _ h,
id ┴
src └────┘ └───────────────────┘
typ └────┘┴└───────────────────┘
doc └────┘ └───────────────────┘
txt └────┘ └───────────────────┘
par └────┘ └───────────────────┘
pid ┴ └───────────────────┘
st ───────────────────────────────┘└─
655 { exact or.imp_left (sublist_cons_of_sublist _) (IH h) },
id └─────────┘ └─────────────────────┘ └┘ ┴
src └────┘└─────────┘┴ └─────────────────────┘└──┘ ┴ └┘
typ └────┘└─────────┘┴ └─────────────────────┘└──┘ └┘┴┴└┘
doc └────┘ ┴ └──┘ ┴ └┘
txt └────┘ ┴ └──┘ ┴ └┘
par └────┘ ┴ └──┘ ┴ └┘
pid ┴ ┴ └──┘ ┴ ┴┴
st ─────┘└───────────────────────────────────────────────────┘└┘└
656 { exact (IH h).imp (cons_sublist_cons _) (mem_cons_of_mem _) } }
id └┘ ┴ └───────────────┘ └─────────────┘
src └────┘ ┴ └────┘ └───────────────┘└──┘ └─────────────┘└──┘
typ └────┘ └┘┴┴└────┘ └───────────────┘└──┘ └─────────────┘└──┘
doc └────┘ ┴ └────┘ └──┘ └──┘
txt └────┘ ┴ └────┘ └──┘ └──┘
par └────┘ ┴ └────┘ └──┘ └──┘
pid ┴ ┴ └────┘ └──┘ └─┘┴
st ────────────────────────────────────────────────────────────────┘└───
657 end
st ──┘
658
659 theorem reverse_sublist {l₁ l₂ : list α} (h : l₁ <+ l₂) : l₁.reverse <+ l₂.reverse :=
id └──┘ ┴ └┘ └┘ └┘ └┘└──────┘ └┘ └┘└──────┘
src └──┘ └┘ └──────┘ └┘ └──────┘
typ └──┘ ┴ └┘ └┘ └┘ └┘└──────┘ └┘ └┘└──────┘
660 begin
st └─────
661 induction h with _ _ _ _ ih _ _ a _ ih, {refl},
id ┴
src └────────┘ └─────────────────────────┘ └──┘
typ └────────┘┴└─────────────────────────┘ └──┘
doc └────────┘ └─────────────────────────┘ └──┘
txt └────────┘ └─────────────────────────┘ └──┘
par └────────┘ └─────────────────────────┘ └──┘
pid ┴ ┴└────────────────────────┘
st ───────────────────────────────────────┘└─────┘└┘└
662 { rw reverse_cons, exact sublist_append_of_sublist_left ih },
id └──────────┘ └────────────────────────────┘ └┘
src └─┘└──────────┘ └────┘└────────────────────────────┘┴ ┴
typ └─┘└──────────┘ └────┘└────────────────────────────┘┴└┘┴
doc └─┘ └────┘ ┴ ┴
txt └─┘ └────┘ ┴ ┴
par └─┘ └────┘ ┴ ┴
pid ┴ ┴ ┴ ┴
st ───┘└─────────────┘└────────────────────────────────────────┘└┘└
663 { rw [reverse_cons, reverse_cons], exact append_sublist_append_of_sublist_right ih [a] }
id └──────────┘ └──────────┘ └────────────────────────────────────┘ └┘ ┴
src └──┘└──────────┘└┘└──────────┘┴ └────┘└────────────────────────────────────┘┴ ┴ ┴
typ └──┘└──────────┘└┘└──────────┘┴ └────┘└────────────────────────────────────┘┴└┘┴ ┴ ┴
doc └──┘ └┘ ┴ └────┘ ┴ ┴ ┴
txt └──┘ └┘ ┴ └────┘ ┴ ┴ ┴
par └──┘ └┘ ┴ └────┘ ┴ ┴ ┴
pid └┘ └┘ ┴ ┴ ┴ ┴ ┴
st ───────────────────┘└────────────┘┴└────────────────────────────────────────────────────┘└─
664 end
st ──┘
665
666 @[simp] theorem reverse_sublist_iff {l₁ l₂ : list α} : l₁.reverse <+ l₂.reverse ↔ l₁ <+ l₂ :=
id └──┘ ┴ └┘└──────┘ └┘ └┘└──────┘ ┴ └┘ └┘ └┘
src └──┘ └──────┘ └┘ └──────┘ ┴ └┘
typ └──┘ ┴ └┘└──────┘ └┘ └┘└──────┘ ┴ └┘ └┘ └┘
doc └──┘
667 ⟨λ h, by have := reverse_sublist h; simp only [reverse_reverse] at this; assumption, reverse_sublist⟩
id ┴ └─────────────┘ ┴ └─────────────┘ └─────────────┘
src └──────┘└─────────────┘┴ └─────────┘└─────────────┘└───────┘ └────────┘ └─────────────┘
typ ┴ └──────┘└─────────────┘┴┴ └─────────┘└─────────────┘└───────┘ └────────┘ └─────────────┘
doc └──────┘ ┴ └─────────┘ └───────┘ └────────┘
txt └──────┘ ┴ └─────────┘ └───────┘ └────────┘
par └──────┘ ┴ └─────────┘ └───────┘ └────────┘
pid └───┘└─┘ ┴ ┴└──┘└┘ ┴┴└─────┘
st └─────────────────────────────────────────────────────────────────────────┘
668
669 @[simp] theorem append_sublist_append_right {l₁ l₂ : list α} (l) : l₁++l <+ l₂++l ↔ l₁ <+ l₂ :=
id └──┘ ┴ └┘└┘┴ └┘ └┘└┘┴ ┴ └┘ └┘ └┘
src └──┘ └┘ └┘ └┘ ┴ └┘
typ └──┘ ┴ └┘└┘┴ └┘ └┘└┘┴ ┴ └┘ └┘ └┘
doc └──┘
670 ⟨λ h, by have := reverse_sublist h; simp only [reverse_append, append_sublist_append_left, reverse_sublist_iff] at this; assumption,
id ┴ └─────────────┘ ┴ └────────────┘ └────────────────────────┘ └─────────────────┘
src └──────┘└─────────────┘┴ └─────────┘└────────────┘└┘└────────────────────────┘└┘└─────────────────┘└───────┘ └────────┘
typ ┴ └──────┘└─────────────┘┴┴ └─────────┘└────────────┘└┘└────────────────────────┘└┘└─────────────────┘└───────┘ └────────┘
doc └──────┘ ┴ └─────────┘ └┘ └┘ └───────┘ └────────┘
txt └──────┘ ┴ └─────────┘ └┘ └┘ └───────┘ └────────┘
par └──────┘ ┴ └─────────┘ └┘ └┘ └───────┘ └────────┘
pid └───┘└─┘ ┴ ┴└──┘└┘ └┘ └┘ ┴┴└─────┘
st └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
671 λ h, append_sublist_append_of_sublist_right h l⟩
id ┴ └────────────────────────────────────┘ ┴ ┴
src └────────────────────────────────────┘
typ ┴ └────────────────────────────────────┘ ┴ ┴
672
673 theorem append_sublist_append {l₁ l₂ r₁ r₂ : list α}
id └──┘ ┴
src └──┘
typ └──┘ ┴
674 (hl : l₁ <+ l₂) (hr : r₁ <+ r₂) : l₁ ++ r₁ <+ l₂ ++ r₂ :=
id └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘
src └┘ └┘ └┘ └┘ └┘
typ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘
675 (append_sublist_append_of_sublist_right hl _).trans
id └────────────────────────────────────┘ └┘ └───┘
src └────────────────────────────────────┘ └───┘
typ └────────────────────────────────────┘ └┘ └───┘
676 ((append_sublist_append_left _).2 hr)
id └────────────────────────┘ ┴ └┘
src └────────────────────────┘ ┴
typ └────────────────────────┘ ┴ └┘
677
678 theorem subset_of_sublist : Π {l₁ l₂ : list α}, l₁ <+ l₂ → l₁ ⊆ l₂
id ┴ └──┘ ┴ └┘ └┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴
typ ┴ └──┘ ┴ └┘ └┘ └┘ └┘ ┴ └┘
679 | ._ ._ sublist.slnil b h := h
id └───────────┘ ┴
src └───────────┘
typ └───────────┘ ┴
680 | ._ ._ (sublist.cons l₁ l₂ a s) b h := mem_cons_of_mem _ (subset_of_sublist s h)
id └──────────┘ ┴ ┴ └─────────────┘ └───────────────┘
src └──────────┘ └─────────────┘
typ └──────────┘ ┴ ┴ └─────────────┘ └───────────────┘
681 | ._ ._ (sublist.cons2 l₁ l₂ a s) b h :=
id └───────────┘ ┴ ┴
src └───────────┘
typ └───────────┘ ┴ ┴
682 match eq_or_mem_of_mem_cons h with
id └───────────────────┘
src └───────────────────┘
typ └───────────────────┘
683 | or.inl h := h ▸ mem_cons_self _ _
id └────┘ ┴ ┴ └───────────┘
src └────┘ ┴ └───────────┘
typ └────┘ ┴ ┴ └───────────┘
684 | or.inr h := mem_cons_of_mem _ (subset_of_sublist s h)
id └────┘ ┴ └─────────────┘ └───────────────┘
src └────┘ └─────────────┘
typ └────┘ ┴ └─────────────┘ └───────────────┘
685 end
686
687 theorem singleton_sublist {a : α} {l} : [a] <+ l ↔ a ∈ l :=
id ┴ ┴┴┴ └┘ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ └┘ ┴ ┴
typ ┴ ┴┴┴ └┘ ┴ ┴ ┴ ┴ ┴
688 ⟨λ h, subset_of_sublist h (mem_singleton_self _), λ h,
id ┴ └───────────────┘ ┴ └────────────────┘ ┴
src └───────────────┘ └────────────────┘
typ ┴ └───────────────┘ ┴ └────────────────┘ ┴
689 let ⟨s, t, e⟩ := mem_split h in e.symm ▸
id └─┘ ┴ └───────┘ ┴ └───┘ ┴
src └───────┘ └───┘ ┴
typ └─┘ ┴ └───────┘ ┴ └───┘ ┴
690 (cons_sublist_cons _ (nil_sublist _)).trans (sublist_append_right _ _)⟩
id └───────────────┘ └─────────┘ └───┘ └──────────────────┘
src └───────────────┘ └─────────┘ └───┘ └──────────────────┘
typ └───────────────┘ └─────────┘ └───┘ └──────────────────┘
691
692 theorem eq_nil_of_sublist_nil {l : list α} (s : l <+ []) : l = [] :=
id └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘
src └──┘ └┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘
693 eq_nil_of_subset_nil $ subset_of_sublist s
id └──────────────────┘ └───────────────┘ ┴
src └──────────────────┘ └───────────────┘
typ └──────────────────┘ └───────────────┘ ┴
694
695 theorem repeat_sublist_repeat (a : α) {m n} : repeat a m <+ repeat a n ↔ m ≤ n :=
id ┴ └────┘ ┴ ┴ └┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └────┘ └┘ └────┘ ┴ ┴
typ ┴ └────┘ ┴ ┴ └┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
696 ⟨λ h, by simpa only [length_repeat] using length_le_of_sublist h,
id ┴ └───────────┘ └──────────────────┘ ┴
src └──────────┘└───────────┘└──────┘└──────────────────┘┴
typ ┴ └──────────┘└───────────┘└──────┘└──────────────────┘┴┴
doc └──────────┘ └──────┘ ┴
txt └──────────┘ └──────┘ ┴
par └──────────┘ └──────┘ ┴
pid ┴└──┘└┘ ┴┴└────┘ ┴
st └──────────────────────────────────────────────────────┘
697 λ h, by induction h; [refl, simp only [*, repeat_succ, sublist.cons]] ⟩
id ┴ ┴ ┴ └─────────┘ └──────────┘
src └────────┘ ┴└──┘ └────────────┘└─────────┘└┘└──────────┘┴
typ ┴ └────────┘┴ ┴└──┘ └────────────┘└─────────┘└┘└──────────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ ┴
st └────────────────────────────────────────────────────────────┘
698
699 theorem eq_of_sublist_of_length_eq : ∀ {l₁ l₂ : list α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
id ┴ └──┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └┘ └────┘ ┴ └────┘ ┴
typ ┴ └──┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
700 | ._ ._ sublist.slnil h := rfl
id └───────────┘ └─┘
src └───────────┘ └─┘
typ └───────────┘ └─┘
701 | ._ ._ (sublist.cons l₁ l₂ a s) h :=
id └──────────┘ ┴
src └──────────┘
typ └──────────┘ ┴
702 absurd (length_le_of_sublist s) $ not_le_of_gt $ by rw h; apply lt_succ_self
id └────┘ └──────────────────┘ └──────────┘ ┴ └──────────┘
src └────┘ └──────────────────┘ └──────────┘ └─┘ └────┘└──────────┘┴
typ └────┘ └──────────────────┘ └──────────┘ └─┘┴ └────┘└──────────┘┴
doc └─┘ └────┘ ┴
txt └─┘ └────┘ ┴
par └─┘ └────┘ ┴
pid ┴ ┴ ┴
st └────────────────────────┘
703 | ._ ._ (sublist.cons2 l₁ l₂ a s) h :=
id └───────────┘
src └───────────┘
typ └───────────┘
704 by rw [length, length] at h; injection h with h; rw eq_of_sublist_of_length_eq s h
id └────┘ └────┘ ┴ └────────────────────────┘ ┴ ┴
src └──┘└────┘└┘└────┘└────┘ └────────┘ └─────┘ └─┘ ┴ ┴ └
typ └──┘└────┘└┘└────┘└────┘ └────────┘┴└─────┘ └─┘└────────────────────────┘┴┴┴┴└
doc └──┘ └┘ └────┘ └────────┘ └─────┘ └─┘ ┴ ┴ └
txt └──┘ └┘ └────┘ └────────┘ └─────┘ └─┘ ┴ ┴ └
par └──┘ └┘ └────┘ └────────┘ └─────┘ └─┘ ┴ ┴ └
pid └┘ └┘ ┴└───┘ ┴ └─────┘ ┴ ┴ ┴ └
st └─────────┘└──────┘┴└────────────────────────────┘└────────────────────────┘└────
705
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
706 theorem eq_of_sublist_of_length_le {l₁ l₂ : list α} (s : l₁ <+ l₂) (h : length l₂ ≤ length l₁) : l₁ = l₂ :=
id └──┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
707 eq_of_sublist_of_length_eq s (le_antisymm (length_le_of_sublist s) h)
id └────────────────────────┘ ┴ └─────────┘ └──────────────────┘ ┴ ┴
src └────────────────────────┘ └─────────┘ └──────────────────┘
typ └────────────────────────┘ ┴ └─────────┘ └──────────────────┘ ┴ ┴
708
709 theorem sublist_antisymm {l₁ l₂ : list α} (s₁ : l₁ <+ l₂) (s₂ : l₂ <+ l₁) : l₁ = l₂ :=
id └──┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └┘
src └──┘ └┘ └┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └┘
710 eq_of_sublist_of_length_le s₁ (length_le_of_sublist s₂)
id └────────────────────────┘ └┘ └──────────────────┘ └┘
src └────────────────────────┘ └──────────────────┘
typ └────────────────────────┘ └┘ └──────────────────┘ └┘
711
712 instance decidable_sublist [decidable_eq α] : ∀ (l₁ l₂ : list α), decidable (l₁ <+ l₂)
id └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └┘ └┘
src └──────────┘ └──┘ └───────┘ └┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └┘ └┘
713 | [] l₂ := is_true $ nil_sublist _
id └┘ └─────┘ └─────────┘
src └┘ └─────┘ └─────────┘
typ └┘ └─────┘ └─────────┘
714 | (a::l₁) [] := is_false $ λh, list.no_confusion $ eq_nil_of_sublist_nil h
id └┘ └┘ └──────┘ ┴ └───────────────┘ └───────────────────┘ ┴
src └┘ └┘ └──────┘ └───────────────┘ └───────────────────┘
typ └┘ └┘ └──────┘ ┴ └───────────────┘ └───────────────────┘ ┴
715 | (a::l₁) (b::l₂) :=
id ┴└┘└┘ ┴└┘└┘
src └┘ └┘
typ ┴└┘└┘ ┴└┘└┘
716 if h : a = b then
id └┘ ┴
src └┘ ┴
typ └┘ ┴
717 decidable_of_decidable_of_iff (decidable_sublist l₁ l₂) $
id └───────────────────────────┘ └───────────────┘
src └───────────────────────────┘
typ └───────────────────────────┘ └───────────────┘
718 by rw [← h]; exact ⟨cons_sublist_cons _, sublist_of_cons_sublist_cons⟩
id ┴ └───────────────┘ └──────────────────────────┘
src └────┘ ┴ └────┘ └───────────────┘└──┘└──────────────────────────┘└─
typ └────┘┴┴ └────┘ └───────────────┘└──┘└──────────────────────────┘└─
doc └────┘ ┴ └────┘ └──┘ └─
txt └────┘ ┴ └────┘ └──┘ └─
par └────┘ ┴ └────┘ └──┘ └─
pid └──┘ ┴ ┴ └──┘ ┴└
st └──────┘┴└───────────────────────────────────────────────────────────
719 else decidable_of_decidable_of_iff (decidable_sublist (a::l₁) l₂)
id └───────────────────────────┘ └───────────────┘ └┘
src ─┘ └───────────────────────────┘ └┘
typ ─┘ └───────────────────────────┘ └───────────────┘ └┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
720 ⟨sublist_cons_of_sublist _, λs, match a, l₁, s, h with
id └─────────────────────┘ ┴ ┴ ┴
src └─────────────────────┘
typ └─────────────────────┘ ┴ ┴ ┴
721 | a, l₁, sublist.cons ._ ._ ._ s', h := s'
id └──────────┘ └┘
src └──────────┘
typ └──────────┘ └┘
722 | ._, ._, sublist.cons2 t ._ ._ s', h := absurd rfl h
id └───────────┘ ┴ └────┘ └─┘
src └───────────┘ └────┘ └─┘
typ └───────────┘ ┴ └────┘ └─┘
723 end⟩
724
725 /- index_of -/
726
727 section index_of
728 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
729
730 @[simp] theorem index_of_nil (a : α) : index_of a [] = 0 := rfl
id ┴ └──────┘ ┴ └┘ ┴ └─┘
src └──────┘ └┘ ┴ └─┘
typ ┴ └──────┘ ┴ └┘ ┴ └─┘
doc └──┘
731
732 theorem index_of_cons (a b : α) (l : list α) : index_of a (b::l) = if a = b then 0 else succ (index_of a l) := rfl
id ┴ └──┘ ┴ └──────┘ ┴ ┴└┘┴ ┴ ┴ ┴ ┴ └──┘ └──────┘ ┴ ┴ └─┘
src └──┘ └──────┘ └┘ ┴ ┴ └──┘ └──────┘ └─┘
typ ┴ └──┘ ┴ └──────┘ ┴ ┴└┘┴ ┴ ┴ ┴ ┴ └──┘ └──────┘ ┴ ┴ └─┘
733
734 theorem index_of_cons_eq {a b : α} (l : list α) : a = b → index_of a (b::l) = 0 :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴└┘┴ ┴
src └──┘ ┴ └──────┘ └┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴└┘┴ ┴
735 assume e, if_pos e
id ┴ └────┘ ┴
src └────┘
typ ┴ └────┘ ┴
736
737 @[simp] theorem index_of_cons_self (a : α) (l : list α) : index_of a (a::l) = 0 :=
id ┴ └──┘ ┴ └──────┘ ┴ ┴└┘┴ ┴
src └──┘ └──────┘ └┘ ┴
typ ┴ └──┘ ┴ └──────┘ ┴ ┴└┘┴ ┴
doc └──┘
738 index_of_cons_eq _ rfl
id └──────────────┘ └─┘
src └──────────────┘ └─┘
typ └──────────────┘ └─┘
739
740 @[simp] theorem index_of_cons_ne {a b : α} (l : list α) : a ≠ b → index_of a (b::l) = succ (index_of a l) :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴└┘┴ ┴ └──┘ └──────┘ ┴ ┴
src └──┘ ┴ └──────┘ └┘ ┴ └──┘ └──────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴└┘┴ ┴ └──┘ └──────┘ ┴ ┴
doc └──┘
741 assume n, if_neg n
id ┴ └────┘ ┴
src └────┘
typ ┴ └────┘ ┴
742
743 theorem index_of_eq_length {a : α} {l : list α} : index_of a l = length l ↔ a ∉ l :=
id ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └──────┘ ┴ └────┘ ┴ ┴
typ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
744 begin
st └─────
745 induction l with b l ih,
id ┴
src └────────┘ └──────────┘
typ └────────┘┴└──────────┘
doc └────────┘ └──────────┘
txt └────────┘ └──────────┘
par └────────┘ └──────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─
746 { exact iff_of_true rfl (not_mem_nil _) },
id └─────────┘ └─┘ └─────────┘
src └────┘└─────────┘┴└─┘┴ └─────────┘└──┘
typ └────┘└─────────┘┴└─┘┴ └─────────┘└──┘
doc └────┘ ┴ ┴ └──┘
txt └────┘ ┴ ┴ └──┘
par └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴ └─┘┴
st ───┘└────────────────────────────────────┘└┘└
747 simp only [length, mem_cons_iff, index_of_cons], split_ifs,
id └────┘ └──────────┘ └───────────┘
src └─────────┘└────┘└┘└──────────┘└┘└───────────┘┴ └───────┘
typ └─────────┘└────┘└┘└──────────┘└┘└───────────┘┴ └───────┘
doc └─────────┘ └┘ └┘ ┴ └───────┘
txt └─────────┘ └┘ └┘ ┴ └───────┘
par └─────────┘ └┘ └┘ ┴ └───────┘
pid ┴└──┘└┘ └┘ └┘ ┴
st ────────────────────────────────────────────────┘└─────────┘└─
748 { exact iff_of_false (by rintro ⟨⟩) (λ H, H $ or.inl h) },
id └──────────┘ └────┘ ┴
src └────┘└──────────┘┴ ┴└───────┘└┘ └──┘ ┴ ┴└────┘┴ └┘
typ └────┘└──────────┘┴ ┴└───────┘└┘ └──┘ ┴ ┴└────┘┴┴└┘
doc └────┘ ┴ ┴└───────┘└┘ └──┘ ┴ ┴ ┴ └┘
txt └────┘ ┴ ┴└───────┘└┘ └──┘ ┴ ┴ ┴ └┘
par └────┘ ┴ ┴└───────┘└┘ └──┘ ┴ ┴ ┴ └┘
pid ┴ ┴ └──────────┘ └──┘ ┴ ┴ ┴ ┴┴
st ───┘└────────────────────┘└────────┘└────────────────────┘└┘└
749 { simp only [h, false_or], rw ← ih, exact succ_inj' }
id ┴ └──────┘ └┘ └───────┘
src └─────────┘ └┘└──────┘┴ └───┘ └────┘└───────┘┴
typ └─────────┘┴└┘└──────┘┴ └───┘└┘ └────┘└───────┘┴
doc └─────────┘ └┘ ┴ └───┘ └────┘ ┴
txt └─────────┘ └┘ ┴ └───┘ └────┘ ┴
par └─────────┘ └┘ ┴ └───┘ └────┘ ┴
pid ┴└──┘└┘ └┘ ┴ └─┘ ┴ ┴
st ──────────────────────────┘└───────┘└────────────────┘└─
750 end
st ──┘
751
752 @[simp] theorem index_of_of_not_mem {l : list α} {a : α} : a ∉ l → index_of a l = length l :=
id └──┘ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴
src └──┘ ┴ └──────┘ ┴ └────┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴
doc └──┘
753 index_of_eq_length.2
id └────────────────┘┴
src └────────────────┘┴
typ └────────────────┘┴
754
755 theorem index_of_le_length {a : α} {l : list α} : index_of a l ≤ length l :=
id ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴
src └──┘ └──────┘ ┴ └────┘
typ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴
756 begin
st └─────
757 induction l with b l ih, {refl},
id ┴
src └────────┘ └──────────┘ └──┘
typ └────────┘┴└──────────┘ └──┘
doc └────────┘ └──────────┘ └──┘
txt └────────┘ └──────────┘ └──┘
par └────────┘ └──────────┘ └──┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─────┘└┘└
758 simp only [length, index_of_cons],
id └────┘ └───────────┘
src └─────────┘└────┘└┘└───────────┘┴
typ └─────────┘└────┘└┘└───────────┘┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st ──────────────────────────────────┘└─
759 by_cases h : a = b, {rw if_pos h, exact nat.zero_le _},
id ┴ ┴ ┴ └────┘ ┴ └─────────┘
src └───────┘ └─┘ ┴┴┴ └─┘└────┘┴ └────┘└─────────┘└┘
typ └───────┘ └─┘┴┴┴┴┴ └─┘└────┘┴┴ └────┘└─────────┘└┘
doc └───────┘ └─┘ ┴ ┴ └─┘ ┴ └────┘ └┘
txt └───────┘ └─┘ ┴ ┴ └─┘ ┴ └────┘ └┘
par └───────┘ └─┘ ┴ ┴ └─┘ ┴ └────┘ └┘
pid ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └┘
st ───────────────────┘└────┘└────┘└┘└───────────────────┘└┘└
760 rw if_neg h, exact succ_le_succ ih
id └────┘ ┴ └──────────┘ └┘
src └─┘└────┘┴ └────┘└──────────┘┴ ┴
typ └─┘└────┘┴┴ └────┘└──────────┘┴└┘┴
doc └─┘ ┴ └────┘ ┴ ┴
txt └─┘ ┴ └────┘ ┴ ┴
par └─┘ ┴ └────┘ ┴ ┴
pid ┴ ┴ ┴ ┴ ┴
st ────────────┘└──────────────────────┘
761 end
st └─┘
762
763 theorem index_of_lt_length {a} {l : list α} : index_of a l < length l ↔ a ∈ l :=
id └──┘ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └──────┘ ┴ └────┘ ┴ ┴
typ └──┘ ┴ └──────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
764 ⟨λh, by_contradiction $ λ al, ne_of_lt h $ index_of_eq_length.2 al,
id ┴ └──────────────┘ └┘ └──────┘ ┴ └────────────────┘┴ └┘
src └──────────────┘ └──────┘ └────────────────┘┴
typ ┴ └──────────────┘ └┘ └──────┘ ┴ └────────────────┘┴ └┘
765 λal, lt_of_le_of_ne index_of_le_length $ λ h, index_of_eq_length.1 h al⟩
id └┘ └────────────┘ └────────────────┘ ┴ └────────────────┘┴ ┴ └┘
src └────────────┘ └────────────────┘ └────────────────┘┴
typ └┘ └────────────┘ └────────────────┘ ┴ └────────────────┘┴ ┴ └┘
766
767 end index_of
768
769 /- nth element -/
770
771 theorem nth_le_of_mem : ∀ {a} {l : list α}, a ∈ l → ∃ n h, nth_le l n h = a
id ┴┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ ┴ └────┘ ┴
typ ┴┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └────┘ ┴ ┴ ┴ ┴ ┴
772 | a (_ :: l) (or.inl rfl) := ⟨0, succ_pos _, rfl⟩
id └┘ └────┘ └─┘ └──────┘ └─┘
src └┘ └────┘ └─┘ └──────┘ └─┘
typ └┘ └────┘ └─┘ └──────┘ └─┘
773 | a (b :: l) (or.inr m) :=
id └┘ └────┘ ┴
src └┘ └────┘
typ └┘ └────┘ ┴
774 let ⟨n, h, e⟩ := nth_le_of_mem m in ⟨n+1, succ_lt_succ h, e⟩
id └─┘ ┴ ┴ ┴ └───────────┘ ┴ └──────────┘
src ┴ └──────────┘
typ └─┘ ┴ ┴ ┴ └───────────┘ ┴ └──────────┘
775
776 theorem nth_le_nth : ∀ {l : list α} {n} h, nth l n = some (nth_le l n h)
id ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └──┘ └────┘ ┴ ┴ ┴
src └──┘ └─┘ ┴ └──┘ └────┘
typ ┴ └──┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └──┘ └────┘ ┴ ┴ ┴
777 | (a :: l) 0 h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
778 | (a :: l) (n+1) h := @nth_le_nth l n _
id └┘ ┴ ┴┴ └────────┘
src └┘ ┴
typ └┘ ┴ ┴┴ └────────┘
779
780 theorem nth_len_le : ∀ {l : list α} {n}, length l ≤ n → nth l n = none
id ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └──┘
src └──┘ └────┘ ┴ └─┘ ┴ └──┘
typ ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └──┘
781 | [] n h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
782 | (a :: l) (n+1) h := nth_len_le (le_of_succ_le_succ h)
id └┘ ┴ ┴ └────────┘ └────────────────┘
src └┘ ┴ └────────────────┘
typ └┘ ┴ ┴ └────────┘ └────────────────┘
783
784 theorem nth_eq_some {l : list α} {n a} : nth l n = some a ↔ ∃ h, nth_le l n h = a :=
id └──┘ ┴ └─┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴┴ └────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └─┘ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴
typ └──┘ ┴ └─┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴┴ └────┘ ┴ ┴ ┴ ┴ ┴
785 ⟨λ e,
id ┴
typ ┴
786 have h : n < length l, from lt_of_not_ge $ λ hn,
id ┴ ┴ └────┘ ┴ └──────────┘ └┘
src ┴ └────┘ └──────────┘
typ ┴ ┴ └────┘ ┴ └──────────┘ └┘
787 by rw nth_len_le hn at e; contradiction,
id └────────┘ └┘
src └─┘└────────┘┴ └───┘ └───────────┘
typ └─┘└────────┘┴└┘└───┘ └───────────┘
doc └─┘ ┴ └───┘ └───────────┘
txt └─┘ ┴ └───┘ └───────────┘
par └─┘ ┴ └───┘ └───────────┘
pid ┴ ┴ └───┘
st └───────────────────────────────────┘
788 ⟨h, by rw nth_le_nth h at e;
id ┴ └────────┘ ┴
src └─┘└────────┘┴ └───┘
typ ┴ └─┘└────────┘┴┴└───┘
doc └─┘ ┴ └───┘
txt └─┘ ┴ └───┘
par └─┘ ┴ └───┘
pid ┴ ┴ └───┘
st └──────────────────────
789 injection e with e; apply nth_le_mem⟩,
id ┴
src └────────┘ └─────┘ └────┘
typ └────────┘┴└─────┘ └────┘
doc └────────┘ └─────┘ └────┘
txt └────────┘ └─────┘ └────┘
par └────────┘ └─────┘ └────┘
pid ┴ └─────┘ ┴
st ───────────────────────────────────────┘
790 λ ⟨h, e⟩, e ▸ nth_le_nth _⟩
id ┴ ┴ ┴ └────────┘
src ┴ └────────┘
typ ┴ ┴ ┴ └────────┘
791
792 theorem nth_of_mem {a} {l : list α} (h : a ∈ l) : ∃ n, nth l n = some a :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴┴ └─┘ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ ┴ ┴ └─┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴┴ └─┘ ┴ ┴ ┴ └──┘ ┴
793 let ⟨n, h, e⟩ := nth_le_of_mem h in ⟨n, by rw [nth_le_nth, e]⟩
id └─┘ ┴ └───────────┘ ┴ └────────┘ ┴
src └───────────┘ └──┘└────────┘└┘ ┴
typ └─┘ ┴ └───────────┘ ┴ └──┘└────────┘└┘┴┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st └─────────────┘└─┘┴
794
795 theorem nth_le_mem : ∀ (l : list α) n h, nth_le l n h ∈ l
id ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
796 | (a :: l) 0 h := mem_cons_self _ _
id └┘ └───────────┘
src └┘ └───────────┘
typ └┘ └───────────┘
797 | (a :: l) (n+1) h := mem_cons_of_mem _ (nth_le_mem l _ _)
id └┘ ┴ ┴ └─────────────┘ └────────┘
src └┘ ┴ └─────────────┘
typ └┘ ┴ ┴ └─────────────┘ └────────┘
798
799 theorem nth_mem {l : list α} {n a} (e : nth l n = some a) : a ∈ l :=
id └──┘ ┴ └─┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ └─┘ ┴ └──┘ ┴
typ └──┘ ┴ └─┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
800 let ⟨h, e⟩ := nth_eq_some.1 e in e ▸ nth_le_mem _ _ _
id └─┘ ┴ └─────────┘┴ ┴ ┴ └────────┘
src └─────────┘┴ ┴ └────────┘
typ └─┘ ┴ └─────────┘┴ ┴ ┴ └────────┘
801
802 theorem mem_iff_nth_le {a} {l : list α} : a ∈ l ↔ ∃ n h, nth_le l n h = a :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ ┴ ┴ └────┘ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └────┘ ┴ ┴ ┴ ┴ ┴
803 ⟨nth_le_of_mem, λ ⟨n, h, e⟩, e ▸ nth_le_mem _ _ _⟩
id └───────────┘ ┴ ┴ ┴ └────────┘
src └───────────┘ ┴ └────────┘
typ └───────────┘ ┴ ┴ ┴ └────────┘
804
805 theorem mem_iff_nth {a} {l : list α} : a ∈ l ↔ ∃ n, nth l n = some a :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └─┘ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ ┴ ┴ ┴ └─┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ └─┘ ┴ ┴ ┴ └──┘ ┴
806 mem_iff_nth_le.trans $ exists_congr $ λ n, nth_eq_some.symm
id └────────────┘└────┘ └──────────┘ ┴ └─────────┘└───┘
src └────────────┘└────┘ └──────────┘ └─────────┘└───┘
typ └────────────┘└────┘ └──────────┘ ┴ └─────────┘└───┘
807
808 @[simp] theorem nth_map (f : α → β) : ∀ l n, nth (map f l) n = (nth l n).map f
id ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴
src └─┘ └─┘ ┴ └─┘ └─┘
typ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴
doc └──┘
809 | [] n := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
810 | (a :: l) 0 := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
811 | (a :: l) (n+1) := nth_map l n
id └┘ ┴ ┴┴ └─────┘
src └┘ ┴
typ └┘ ┴ ┴┴ └─────┘
812
813 theorem nth_le_map (f : α → β) {l n} (H1 H2) : nth_le (map f l) n H1 = f (nth_le l n H2) :=
id ┴ ┴ └────┘ └─┘ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ ┴ ┴ └┘
src └────┘ └─┘ ┴ └────┘
typ ┴ ┴ └────┘ └─┘ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ ┴ ┴ └┘
814 option.some.inj $ by rw [← nth_le_nth, nth_map, nth_le_nth]; refl
id └─────────────┘ └────────┘ └─────┘ └────────┘
src └─────────────┘ └────┘└────────┘└┘└─────┘└┘└────────┘┴ └────
typ └─────────────┘ └────┘└────────┘└┘└─────┘└┘└────────┘┴ └────
doc └────┘ └┘ └┘ ┴ └────
txt └────┘ └┘ └┘ ┴ └────
par └────┘ └┘ └┘ ┴ └────
pid └──┘ └┘ └┘ ┴ └
st └───────────────┘└───────┘└──────────┘┴└──────
815
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
816 /-- A version of `nth_le_map` that can be used for rewriting. -/
817 theorem nth_le_map_rev (f : α → β) {l n} (H) :
id ┴ ┴
typ ┴ ┴
818 f (nth_le l n H) = nth_le (map f l) n ((length_map f l).symm ▸ H) :=
id ┴ └────┘ ┴ ┴ ┴ ┴ └────┘ └─┘ ┴ ┴ ┴ └────────┘ ┴ ┴ └──┘ ┴ ┴
src └────┘ ┴ └────┘ └─┘ └────────┘ └──┘ ┴
typ ┴ └────┘ ┴ ┴ ┴ ┴ └────┘ └─┘ ┴ ┴ ┴ └────────┘ ┴ ┴ └──┘ ┴ ┴
819 (nth_le_map f _ _).symm
id └────────┘ ┴ └──┘
src └────────┘ └──┘
typ └────────┘ ┴ └──┘
820
821 @[simp] theorem nth_le_map' (f : α → β) {l n} (H) :
id ┴ ┴
typ ┴ ┴
doc └──┘
822 nth_le (map f l) n H = f (nth_le l n (length_map f l ▸ H)) :=
id └────┘ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
src └────┘ └─┘ ┴ └────┘ └────────┘ ┴
typ └────┘ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
823 nth_le_map f _ _
id └────────┘ ┴
src └────────┘
typ └────────┘ ┴
824
825 @[simp] lemma nth_le_singleton (a : α) {n : ℕ} (hn : n < 1) :
id ┴ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ ┴
doc └──┘
826 nth_le [a] n hn = a :=
id └────┘ ┴┴┴ ┴ └┘ ┴ ┴
src └────┘ ┴ ┴ ┴
typ └────┘ ┴┴┴ ┴ └┘ ┴ ┴
827 have hn0 : n = 0 := le_zero_iff.1 (le_of_lt_succ hn),
id ┴ ┴ └─────────┘┴ └───────────┘ └┘
src ┴ └─────────┘┴ └───────────┘
typ ┴ ┴ └─────────┘┴ └───────────┘ └┘
828 by subst hn0; refl
id └─┘
src └────┘ └────
typ └────┘└─┘ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └────────────────
829
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
830 lemma nth_le_append : ∀ {l₁ l₂ : list α} {n : ℕ} (hn₁) (hn₂),
id ┴ └──┘ ┴ ┴ └─┘ └─┘
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ └─┘ └─┘
831 (l₁ ++ l₂).nth_le n hn₁ = l₁.nth_le n hn₂
id └┘ └┘ └┘ └────┘ ┴ └─┘ ┴ └┘└─────┘ ┴ └─┘
src └┘ └────┘ ┴ └─────┘
typ └┘ └┘ └┘ └────┘ ┴ └─┘ ┴ └┘└─────┘ ┴ └─┘
832 | [] _ n hn₁ hn₂ := (not_lt_zero _ hn₂).elim
id └┘ └─┘ └─────────┘ └──┘
src └┘ └─────────┘ └──┘
typ └┘ └─┘ └─────────┘ └──┘
833 | (a::l) _ 0 hn₁ hn₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
834 | (a::l) _ (n+1) hn₁ hn₂ := by simp only [nth_le, cons_append];
id └┘ ┴ └────┘ └─────────┘
src └┘ ┴ └─────────┘└────┘└┘└─────────┘┴
typ └┘ ┴ └─────────┘└────┘└┘└─────────┘┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st └─────────────────────────────────
835 exact nth_le_append _ _
id └───────────┘
src └────┘ └────
typ └────┘└───────────┘└────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └──┘└
st ─────────────────────────────────────────────────
836
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
837 lemma nth_le_append_right_aux {l₁ l₂ : list α} {n : ℕ}
id └──┘ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴
838 (h₁ : l₁.length ≤ n) (h₂ : n < (l₁ ++ l₂).length) : n - l₁.length < l₂.length :=
id └┘└─────┘ ┴ ┴ ┴ ┴ └┘ └┘ └┘ └────┘ ┴ ┴ └┘└─────┘ ┴ └┘└─────┘
src └─────┘ ┴ ┴ └┘ └────┘ ┴ └─────┘ ┴ └─────┘
typ └┘└─────┘ ┴ ┴ ┴ ┴ └┘ └┘ └┘ └────┘ ┴ ┴ └┘└─────┘ ┴ └┘└─────┘
839 begin
st └─────
840 rw list.length_append at h₂,
id └────────────────┘
src └─┘└────────────────┘└────┘
typ └─┘└────────────────┘└────┘
doc └─┘ └────┘
txt └─┘ └────┘
par └─┘ └────┘
pid ┴ └────┘
st ────────────────────────────┘└─
841 convert (nat.sub_lt_sub_right_iff h₁).mpr h₂,
id └──────────────────────┘ └┘ └┘
src └──────┘ └──────────────────────┘┴ └────┘
typ └──────┘ └──────────────────────┘┴└┘└────┘└┘
doc └──────┘ ┴ └────┘
txt └──────┘ ┴ └────┘
par └──────┘ ┴ └────┘
pid ┴ ┴ └────┘
st ─────────────────────────────────────────────┘└─
842 simp,
src └──┘
typ └──┘
doc └──┘
txt └──┘
par └──┘
st ─────┘└─
843 end
st ──┘
844
845 lemma nth_le_append_right : ∀ {l₁ l₂ : list α} {n : ℕ} (h₁ : l₁.length ≤ n) (h₂),
id ┴ └──┘ ┴ ┴ └┘└─────┘ ┴ ┴ └┘
src └──┘ ┴ └─────┘ ┴
typ ┴ └──┘ ┴ ┴ └┘└─────┘ ┴ ┴ └┘
846 (l₁ ++ l₂).nth_le n h₂ = l₂.nth_le (n - l₁.length) (nth_le_append_right_aux h₁ h₂)
id └┘ └┘ └┘ └────┘ ┴ └┘ ┴ └┘└─────┘ ┴ ┴ └┘└─────┘ └─────────────────────┘ └┘ └┘
src └┘ └────┘ ┴ └─────┘ ┴ └─────┘ └─────────────────────┘
typ └┘ └┘ └┘ └────┘ ┴ └┘ ┴ └┘└─────┘ ┴ ┴ └┘└─────┘ └─────────────────────┘ └┘ └┘
847 | [] _ n h₁ h₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
848 | (a :: l) _ (n+1) h₁ h₂ :=
id └┘ ┴
src └┘ ┴
typ └┘ ┴
849 begin
st └─────
850 dsimp,
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
st ────────┘└─
851 conv { to_rhs, congr, skip, rw [←nat.sub_sub, nat.sub.right_comm, nat.add_sub_cancel], },
id └─────────┘ └────────────────┘ └────────────────┘
src └─────┘└────┘└┘└───┘└┘└──┘└┘└───┘└─────────┘└┘└────────────────┘└┘└────────────────┘┴└─┘
typ └─────┘└────┘└┘└───┘└┘└──┘└┘└───┘└─────────┘└┘└────────────────┘└┘└────────────────┘┴└─┘
txt └─────┘└────┘└┘└───┘└┘└──┘└┘└───┘ └┘ └┘ ┴└─┘
par └─────┘└────┘└┘└───┘└┘└──┘└┘└───┘ └┘ └┘ ┴└─┘
pid ┴└──────────────────────────┘ └┘ └┘ └──┘
st ─────────┘└─────┘└─────┘└────┘└────────────────┘└──────────────────┘└──────────────────┘ └──┘└
852 rw nth_le_append_right (nat.lt_succ_iff.mp h₁),
id └─────────────────┘ └────────────────┘ └┘
src └─┘ ┴ └────────────────┘┴ ┴
typ └─┘└─────────────────┘┴ └────────────────┘┴└┘┴
doc └─┘ ┴ ┴ ┴
txt └─┘ ┴ ┴ ┴
par └─┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ─────────────────────────────────────────────────┘└─
853 end
st ────┘
854
855 @[simp] lemma nth_le_repeat (a : α) {n m : ℕ} (h : m < n) :
id ┴ ┴ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ ┴ ┴
doc └──┘
856 (list.repeat a n).nth_le m (by rwa list.length_repeat) = a :=
id └─────────┘ ┴ ┴ └────┘ ┴ └────────────────┘ ┴ ┴
src └─────────┘ └────┘ └──┘└────────────────┘ ┴
typ └─────────┘ ┴ ┴ └────┘ ┴ └──┘└────────────────┘ ┴ ┴
doc └──┘
txt └──┘
par └──┘
pid ┴
st └─────────────────────┘
857 eq_of_mem_repeat (nth_le_mem _ _ _)
id └──────────────┘ └────────┘
src └──────────────┘ └────────┘
typ └──────────────┘ └────────┘
858
859 lemma nth_append {l₁ l₂ : list α} {n : ℕ} (hn : n < l₁.length) :
id └──┘ ┴ ┴ ┴ ┴ └┘└─────┘
src └──┘ ┴ ┴ └─────┘
typ └──┘ ┴ ┴ ┴ ┴ └┘└─────┘
860 (l₁ ++ l₂).nth n = l₁.nth n :=
id └┘ └┘ └┘ └─┘ ┴ ┴ └┘└──┘ ┴
src └┘ └─┘ ┴ └──┘
typ └┘ └┘ └┘ └─┘ ┴ ┴ └┘└──┘ ┴
861 have hn' : n < (l₁ ++ l₂).length := lt_of_lt_of_le hn
id ┴ ┴ └┘ └┘ └┘ └────┘ └────────────┘ └┘
src ┴ └┘ └────┘ └────────────┘
typ ┴ ┴ └┘ └┘ └┘ └────┘ └────────────┘ └┘
862 (by rw length_append; exact le_add_right _ _),
id └───────────┘ └──────────┘
src └─┘└───────────┘ └────┘└──────────┘└──┘
typ └─┘└───────────┘ └────┘└──────────┘└──┘
doc └─┘ └────┘ └──┘
txt └─┘ └────┘ └──┘
par └─┘ └────┘ └──┘
pid ┴ ┴ └──┘
st └───────────────────────────────────────┘
863 by rw [nth_le_nth hn, nth_le_nth hn', nth_le_append]
id └────────┘ └┘ └────────┘ └─┘ └───────────┘
src └──┘└────────┘┴ └┘└────────┘┴ └┘└───────────┘└─
typ └──┘└────────┘┴└┘└┘└────────┘┴└─┘└┘└───────────┘└─
doc └──┘ ┴ └┘ ┴ └┘ └─
txt └──┘ ┴ └┘ ┴ └┘ └─
par └──┘ ┴ └┘ ┴ └┘ └─
pid └┘ ┴ └┘ ┴ └┘ ┴└
st └────────────────┘└──────────────┘└─────────────┘┴└
864
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
865 lemma last_eq_nth_le : ∀ (l : list α) (h : l ≠ []),
id ┴ └──┘ ┴ ┴ ┴ └┘
src └──┘ ┴ └┘
typ ┴ └──┘ ┴ ┴ ┴ └┘
866 last l h = l.nth_le (l.length - 1) (sub_lt (length_pos_of_ne_nil h) one_pos)
id └──┘ ┴ ┴ ┴ ┴└─────┘ ┴└─────┘ ┴ └────┘ └──────────────────┘ ┴ └─────┘
src └──┘ ┴ └─────┘ └─────┘ ┴ └────┘ └──────────────────┘ └─────┘
typ └──┘ ┴ ┴ ┴ ┴└─────┘ ┴└─────┘ ┴ └────┘ └──────────────────┘ ┴ └─────┘
867 | [] h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
868 | [a] h := by rw [last_singleton, nth_le_singleton]
id ┴ ┴ └────────────┘ └──────────────┘
src ┴ ┴ └──┘└────────────┘└┘└──────────────┘└┘
typ ┴ ┴ └──┘└────────────┘└┘└──────────────┘└┘
doc └──┘ └┘ └┘
txt └──┘ └┘ └┘
par └──┘ └┘ └┘
pid └┘ └┘ ┴┴
st └─────────────────┘└────────────────┘┴┴
869 | (a :: b :: l) h := by { rw [last_cons, last_eq_nth_le (b :: l)],
id └┘ └┘ └───────┘ └────────────┘ ┴ ┴
src └┘ └┘ └──┘└───────┘└┘ ┴ ┴ ┴ └┘
typ └┘ └┘ └──┘└───────┘└┘└────────────┘┴ ┴┴ ┴┴└┘
doc └──┘ └┘ ┴ ┴ ┴ └┘
txt └──┘ └┘ ┴ ┴ ┴ └┘
par └──┘ └┘ ┴ ┴ ┴ └┘
pid └┘ └┘ ┴ ┴ ┴ └┘
st └──────────────┘└───────────────────────┘└──
870 refl, exact cons_ne_nil b l }
id └─────────┘ ┴ ┴
src └──┘ └────┘└─────────┘┴ ┴ ┴
typ └──┘ └────┘└─────────┘┴┴┴┴┴
doc └──┘ └────┘ ┴ ┴ ┴
txt └──┘ └────┘ ┴ ┴ ┴
par └──┘ └────┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ─────────────────────────────┘└──────────────────────┘└┘
871
872 @[simp] lemma nth_concat_length: ∀ (l : list α) (a : α), (l ++ [a]).nth l.length = a
id ┴ └──┘ ┴ ┴ ┴ └┘ ┴┴┴ └─┘ ┴└─────┘ ┴ ┴
src └──┘ └┘ ┴ ┴ └─┘ └─────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ └┘ ┴┴┴ └─┘ ┴└─────┘ ┴ ┴
doc └──┘
873 | [] a := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
874 | (b::l) a := by rw [cons_append, length_cons, nth, nth_concat_length]
id └┘ └─────────┘ └─────────┘ └─┘ └───────────────┘
src └┘ └──┘└─────────┘└┘└─────────┘└┘└─┘└┘ └─
typ └┘ └──┘└─────────┘└┘└─────────┘└┘└─┘└┘└───────────────┘└─
doc └──┘ └┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └┘ └─
par └──┘ └┘ └┘ └┘ └─
pid └┘ └┘ └┘ └┘ ┴└
st └──────────────┘└───────────┘└───┘└─────────────────┘┴└
875
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
876 @[ext]
doc └─┘
877 theorem ext : ∀ {l₁ l₂ : list α}, (∀n, nth l₁ n = nth l₂ n) → l₁ = l₂
id ┴ └──┘ ┴ ┴ └─┘ └┘ ┴ ┴ └─┘ └┘ ┴ └┘ ┴ └┘
src └──┘ └─┘ ┴ └─┘ ┴
typ ┴ └──┘ ┴ ┴ └─┘ └┘ ┴ ┴ └─┘ └┘ ┴ └┘ ┴ └┘
878 | [] [] h := rfl
id └┘ └┘ └─┘
src └┘ └┘ └─┘
typ └┘ └┘ └─┘
879 | (a::l₁) [] h := by have h0 := h 0; contradiction
id └┘ └┘ ┴
src └┘ └┘ └─────────┘ └┘ └────────────┘
typ └┘ └┘ └─────────┘┴└┘ └────────────┘
doc └─────────┘ └┘ └────────────┘
txt └─────────┘ └┘ └────────────┘
par └─────────┘ └┘ └────────────┘
pid └─────┘┴└─┘ ┴┴ ┴
st └─────────────────────────────┘
880 | [] (a'::l₂) h := by have h0 := h 0; contradiction
id └┘ └┘ ┴
src └┘ └┘ └─────────┘ └┘ └────────────┘
typ └┘ └┘ └─────────┘┴└┘ └────────────┘
doc └─────────┘ └┘ └────────────┘
txt └─────────┘ └┘ └────────────┘
par └─────────┘ └┘ └────────────┘
pid └─────┘┴└─┘ ┴┴ ┴
st └─────────────────────────────┘
881 | (a::l₁) (a'::l₂) h := by have h0 : some a = some a' := h 0; injection h0 with aa;
id └┘ └┘ ┴ ┴ └──┘ └┘ ┴ └┘
src └┘ └┘ └────────┘ ┴ ┴┴┴└──┘┴ └──┘ └┘ └────────┘ └──────┘
typ └┘ └┘ └────────┘ ┴┴┴┴┴└──┘┴└┘└──┘┴└┘ └────────┘└┘└──────┘
doc └────────┘ ┴ ┴ ┴ ┴ └──┘ └┘ └────────┘ └──────┘
txt └────────┘ ┴ ┴ ┴ ┴ └──┘ └┘ └────────┘ └──────┘
par └────────┘ ┴ ┴ ┴ ┴ └──┘ └┘ └────────┘ └──────┘
pid └─────┘└─┘ ┴ ┴ ┴ ┴ └──┘ ┴┴ ┴ └──────┘
st └─────────────────────────────────────────────────────────
882 simp only [aa, ext (λn, h (n+1))]; split; refl
id └┘ └─┘ ┴ ┴
src └─────────┘ └┘ ┴ └─┘ ┴ ┴└──┘ └───┘ └────
typ └─────────┘└┘└┘└─┘┴ └─┘┴┴ ┴└──┘ └───┘ └────
doc └─────────┘ └┘ ┴ └─┘ ┴ └──┘ └───┘ └────
txt └─────────┘ └┘ ┴ └─┘ ┴ └──┘ └───┘ └────
par └─────────┘ └┘ ┴ └─┘ ┴ └──┘ └───┘ └────
pid ┴└──┘└┘ └┘ ┴ └─┘ ┴ └──┘ └
st ───────────────────────────────────────────────────
883
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
884 theorem ext_le {l₁ l₂ : list α} (hl : length l₁ = length l₂) (h : ∀n h₁ h₂, nth_le l₁ n h₁ = nth_le l₂ n h₂) : l₁ = l₂ :=
id └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘ ┴ └┘ └┘ └────┘ └┘ ┴ └┘ ┴ └────┘ └┘ ┴ └┘ └┘ ┴ └┘
src └──┘ └────┘ ┴ └────┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘ ┴ └┘ └┘ └────┘ └┘ ┴ └┘ ┴ └────┘ └┘ ┴ └┘ └┘ ┴ └┘
885 ext $ λn, if h₁ : n < length l₁
id └─┘ ┴ └┘ ┴ ┴ └────┘ └┘
src └─┘ └┘ ┴ └────┘
typ └─┘ ┴ └┘ ┴ ┴ └────┘ └┘
886 then by rw [nth_le_nth, nth_le_nth, h n h₁ (by rwa [← hl])]
id └────────┘ └────────┘ ┴ ┴ └┘ └┘
src └──┘└────────┘└┘└────────┘└┘ ┴ ┴ ┴ ┴└─────┘ ┴└──
typ └──┘└────────┘└┘└────────┘└┘┴┴┴┴└┘┴ └──────┘└┘└───
doc └──┘ └┘ └┘ ┴ ┴ ┴ ┴└─────┘ ┴└──
txt └──┘ └┘ └┘ ┴ ┴ ┴ ┴└─────┘ ┴└──
par └──┘ └┘ └┘ ┴ ┴ ┴ └──────┘ └───
pid └┘ └┘ └┘ ┴ ┴ ┴ └──────┘ └─┘└
st └─────────────┘└──────────┘└──────────┘└────────┘┴┴┴└
887 else let h₁ := le_of_not_gt h₁ in by { rw [nth_len_le h₁, nth_len_le], rwa [←hl], }
id └─┘ └┘ └──────────┘ └┘ └────────┘ └┘ └────────┘ └┘
src ─┘ └──────────┘ └──┘└────────┘┴ └┘└────────┘┴ └────┘ ┴
typ ─┘ └─┘ └┘ └──────────┘ └┘ └──┘└────────┘┴└┘└┘└────────┘┴ └────┘└┘┴
doc ─┘ └──┘ ┴ └┘ ┴ └────┘ ┴
txt ─┘ └──┘ ┴ └┘ ┴ └────┘ ┴
par ─┘ └──┘ ┴ └┘ ┴ └────┘ ┴
pid ─┘ └┘ ┴ └┘ ┴ └─┘ ┴
st ─┘ └──────────────────┘└──────────┘└─────────┘┴└──┘
888
889 @[simp] theorem index_of_nth_le [decidable_eq α] {a : α} : ∀ {l : list α} h, nth_le l (index_of a l) h = a
id └──────────┘ ┴ ┴ ┴ └──┘ ┴ ┴ └────┘ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴
src └──────────┘ └──┘ └────┘ └──────┘ ┴
typ └──────────┘ ┴ ┴ ┴ └──┘ ┴ ┴ └────┘ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘
890 | (b::l) h := by by_cases h' : a = b; simp only [h', if_pos, if_false, index_of_cons, nth_le, @index_of_nth_le l]
id └┘ ┴ ┴ ┴ └┘ └────┘ └──────┘ └───────────┘ └────┘ └─────────────┘ ┴
src └┘ └───────┘ └─┘ ┴┴┴ └─────────┘ └┘└────┘└┘└──────┘└┘└───────────┘└┘└────┘└┘ ┴ └─
typ └┘ └───────┘ └─┘┴┴┴┴┴ └─────────┘└┘└┘└────┘└┘└──────┘└┘└───────────┘└┘└────┘└┘ └─────────────┘┴┴└─
doc └───────┘ └─┘ ┴ ┴ └─────────┘ └┘ └┘ └┘ └┘ └┘ ┴ └─
txt └───────┘ └─┘ ┴ ┴ └─────────┘ └┘ └┘ └┘ └┘ └┘ ┴ └─
par └───────┘ └─┘ ┴ ┴ └─────────┘ └┘ └┘ └┘ └┘ └┘ ┴ └─
pid ┴ └─┘ ┴ ┴ ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ ┴ ┴└
st └─────────────────────────────────────────────────────────────────────────────────────────────────
891
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
892 @[simp] theorem index_of_nth [decidable_eq α] {a : α} {l : list α} (h : a ∈ l) : nth l (index_of a l) = some a :=
id └──────────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─┘ ┴ └──────┘ ┴ ┴ ┴ └──┘ ┴
src └──────────┘ └──┘ ┴ └─┘ └──────┘ ┴ └──┘
typ └──────────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └─┘ ┴ └──────┘ ┴ ┴ ┴ └──┘ ┴
doc └──┘
893 by rw [nth_le_nth, index_of_nth_le (index_of_lt_length.2 h)]
id └────────┘ └─────────────┘ └────────────────┘ ┴
src └──┘└────────┘└┘└─────────────┘┴ └────────────────┘└─┘ └──
typ └──┘└────────┘└┘└─────────────┘┴ └────────────────┘└─┘┴└──
doc └──┘ └┘ ┴ └─┘ └──
txt └──┘ └┘ ┴ └─┘ └──
par └──┘ └┘ ┴ └─┘ └──
pid └┘ └┘ ┴ └─┘ └┘└
st └─────────────┘└────────────────────────────────────────┘┴└
894
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
895 theorem nth_le_reverse_aux1 : ∀ (l r : list α) (i h1 h2), nth_le (reverse_core l r) (i + length l) h1 = nth_le r i h2
id ┴ └──┘ ┴ ┴ └┘ └┘ └────┘ └──────────┘ ┴ ┴ ┴ ┴ └────┘ ┴ └┘ ┴ └────┘ ┴ ┴ └┘
src └──┘ └────┘ └──────────┘ ┴ └────┘ ┴ └────┘
typ ┴ └──┘ ┴ ┴ └┘ └┘ └────┘ └──────────┘ ┴ ┴ ┴ ┴ └────┘ ┴ └┘ ┴ └────┘ ┴ ┴ └┘
896 | [] r i := λh1 h2, rfl
id └┘ └┘ └┘ └─┘
src └┘ └─┘
typ └┘ └┘ └┘ └─┘
897 | (a :: l) r i := by rw (show i + length (a :: l) = i + 1 + length l, from add_right_comm i (length l) 1); exact
id └┘ ┴ ┴ ┴ └────────────┘ ┴ └────┘ ┴
src └┘ └─┘ ┴ ┴┴┴ ┴ ┴ ┴ └┘┴┴ ┴ └─┘ ┴ ┴ └─────┘└────────────┘┴ ┴ └────┘┴ └──┘ └─────
typ └┘ └─┘ ┴ ┴┴┴ ┴ ┴┴ ┴ └┘┴┴ ┴ └─┘ ┴ ┴ └─────┘└────────────┘┴┴┴ └────┘┴┴└──┘ └─────
doc └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ ┴ └──┘ └─────
txt └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ ┴ └──┘ └─────
par └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ ┴ └──┘ └─────
pid ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ ┴ └──┘ └
st └────────────────────────────────────────────────────────────────────────────────────────────
898 λh1 h2, nth_le_reverse_aux1 l (a :: r) (i+1) h1 (succ_lt_succ h2)
id └─────────────────┘ ┴ ┴ ┴ ┴ └──────────┘
src ─┘ └─────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ └──────────┘┴ └─
typ ─┘ └─────┘└─────────────────┘┴┴┴ ┴┴ ┴┴└┘ ┴ └─┘ ┴ └──────────┘┴ └─
doc ─┘ └─────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └─
txt ─┘ └─────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └─
par ─┘ └─────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └─
pid ─┘ └─────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ ┴└
st ────────────────────────────────────────────────────────────────────
899
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
900 lemma index_of_inj [decidable_eq α] {l : list α} {x y : α}
id └──────────┘ ┴ └──┘ ┴ ┴
src └──────────┘ └──┘
typ └──────────┘ ┴ └──┘ ┴ ┴
901 (hx : x ∈ l) (hy : y ∈ l) : index_of x l = index_of y l ↔ x = y :=
id ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ └──────┘ ┴ └──────┘ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴
902 ⟨λ h, have nth_le l (index_of x l) (index_of_lt_length.2 hx) =
id ┴ └────┘ ┴ └──────┘ ┴ ┴ └────────────────┘┴ └┘ ┴
src └────┘ └──────┘ └────────────────┘┴ ┴
typ ┴ └────┘ ┴ └──────┘ ┴ ┴ └────────────────┘┴ └┘ ┴
903 nth_le l (index_of y l) (index_of_lt_length.2 hy),
id └────┘ ┴ └──────┘ ┴ ┴ └────────────────┘┴ └┘
src └────┘ └──────┘ └────────────────┘┴
typ └────┘ ┴ └──────┘ ┴ ┴ └────────────────┘┴ └┘
904 by simp only [h],
id ┴
src └─────────┘ ┴
typ └─────────┘┴┴
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid ┴└──┘└┘ ┴
st └────────────┘
905 by simpa only [index_of_nth_le],
id └─────────────┘
src └──────────┘└─────────────┘┴
typ └──────────┘└─────────────┘┴
doc └──────────┘ ┴
txt └──────────┘ ┴
par └──────────┘ ┴
pid ┴└──┘└┘ ┴
st └───────────────────────────┘
906 λ h, by subst h⟩
id ┴ ┴
src └────┘
typ ┴ └────┘┴
doc └────┘
txt └────┘
par └────┘
pid ┴
st └──────┘
907
908 theorem nth_le_reverse_aux2 : ∀ (l r : list α) (i : nat) (h1) (h2),
id ┴ └──┘ ┴ └─┘ └┘ └┘
src └──┘ └─┘
typ ┴ └──┘ ┴ └─┘ └┘ └┘
909 nth_le (reverse_core l r) (length l - 1 - i) h1 = nth_le l i h2
id └────┘ └──────────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ └┘
src └────┘ └──────────┘ └────┘ ┴ ┴ ┴ └────┘
typ └────┘ └──────────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ └┘
910 | [] r i h1 h2 := absurd h2 (not_lt_zero _)
id └┘ └┘ └────┘ └─────────┘
src └┘ └────┘ └─────────┘
typ └┘ └┘ └────┘ └─────────┘
911 | (a :: l) r 0 h1 h2 := begin
id └┘
src └┘
typ └┘
st └─────
912 have aux := nth_le_reverse_aux1 l (a :: r) 0,
id └─────────────────┘ ┴ ┴ ┴
src └──────────┘└─────────────────┘┴ ┴ ┴ ┴ └─┘
typ └──────────┘└─────────────────┘┴┴┴ ┴┴ ┴┴└─┘
doc └──────────┘ ┴ ┴ ┴ ┴ └─┘
txt └──────────┘ ┴ ┴ ┴ ┴ └─┘
par └──────────┘ ┴ ┴ ┴ ┴ └─┘
pid └──────┘┴└─┘ ┴ ┴ ┴ ┴ └┘┴
st ───────────────────────────────────────────────┘└─
913 rw zero_add at aux,
id └──────┘
src └─┘└──────┘└─────┘
typ └─┘└──────┘└─────┘
doc └─┘ └─────┘
txt └─┘ └─────┘
par └─┘ └─────┘
pid ┴ └─────┘
st ─────────────────────┘└─
914 exact aux _ (zero_lt_succ _)
id └─┘ └──────────┘
src └────┘ └─┘ └──────────┘└───
typ └────┘└─┘└─┘ └──────────┘└───
doc └────┘ └─┘ └───
txt └────┘ └─┘ └───
par └────┘ └─┘ └───
pid ┴ └─┘ └─┘└
st ─────────────────────────────────
915 end
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
916 | (a :: l) r (i+1) h1 h2 := begin
id └┘ ┴
src └┘ ┴
typ └┘ ┴
st └─────
917 have aux := nth_le_reverse_aux2 l (a :: r) i,
id └─────────────────┘ ┴ ┴ ┴ ┴
src └──────────┘ ┴ ┴ ┴ ┴ └┘
typ └──────────┘└─────────────────┘┴┴┴ ┴┴ ┴┴└┘┴
doc └──────────┘ ┴ ┴ ┴ ┴ └┘
txt └──────────┘ ┴ ┴ ┴ ┴ └┘
par └──────────┘ ┴ ┴ ┴ ┴ └┘
pid └──────┘┴└─┘ ┴ ┴ ┴ ┴ └┘
st ───────────────────────────────────────────────┘└─
918 have heq := calc length (a :: l) - 1 - (i + 1)
id ┴ ┴ ┴
src └──────────┘ ┴ ┴ ┴ ┴ └┘┴└─┘ ┴ ┴┴└───
typ └──────────┘ ┴ ┴ ┴┴ ┴ └┘┴└─┘ ┴ ┴┴└───
doc └──────────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └───
txt └──────────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └───
par └──────────┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └───
pid └──────┘┴└─┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └───
st ───────────────────────────────────────────────────
919 = length l - (1 + i) : by rw add_comm; refl
id └──────┘
src ─────────┘ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ ┴└─┘└──────┘└┘└────
typ ─────────┘ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ ┴└─┘└──────┘└┘└────
doc ─────────┘ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ ┴└─┘ └┘└────
txt ─────────┘ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ ┴└─┘ └┘└────
par ─────────┘ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ ┴└─┘ └┘└────
pid ─────────┘ ┴ ┴ ┴ ┴ └┘ ┴ └──┘ └──┘ └──────
st ──────────────────────────────────┘└──────────────────
920 ... = length l - 1 - i : by rw nat.sub_sub,
id └────┘ ┴ ┴ └─────────┘
src ─────┘└──┘ ┴└────┘┴ ┴ └─┘ ┴ └───┘ ┴└─┘└─────────┘
typ ─────┘└──┘ ┴└────┘┴┴┴ └─┘ ┴┴└───┘ ┴└─┘└─────────┘
doc ─────┘└──┘ ┴ ┴ ┴ └─┘ ┴ └───┘ ┴└─┘
txt ─────┘└──┘ ┴ ┴ ┴ └─┘ ┴ └───┘ ┴└─┘
par ─────┘└──┘ ┴ ┴ ┴ └─┘ ┴ └───┘ ┴└─┘
pid ─────────┘ ┴ ┴ ┴ └─┘ ┴ └───┘ └──┘
st ─────┘└───────────────────────────┘└─────────────┘└─
921 rw [← heq] at aux,
id └─┘
src └────┘└─┘└──────┘
typ └────┘└─┘└──────┘
doc └────┘ └──────┘
txt └────┘ └──────┘
par └────┘ └──────┘
pid └──┘ ┴└─────┘
st ────────────┘┴└─────┘└─
922 apply aux
src └────┘ └
typ └────┘ └
doc └────┘ └
txt └────┘ └
par └────┘ └
pid ┴ └
st ──────────────
923 end
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
924
925 @[simp] theorem nth_le_reverse (l : list α) (i : nat) (h1 h2) :
id └──┘ ┴ └─┘
src └──┘ └─┘
typ └──┘ ┴ └─┘
doc └──┘
926 nth_le (reverse l) (length l - 1 - i) h1 = nth_le l i h2 :=
id └────┘ └─────┘ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ └┘
src └────┘ └─────┘ └────┘ ┴ ┴ ┴ └────┘
typ └────┘ └─────┘ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ └┘
927 nth_le_reverse_aux2 _ _ _ _ _
id └─────────────────┘
src └─────────────────┘
typ └─────────────────┘
928
929 lemma modify_nth_tail_modify_nth_tail {f g : list α → list α} (m : ℕ) :
id └──┘ ┴ └──┘ ┴ ┴
src └──┘ └──┘ ┴
typ └──┘ ┴ └──┘ ┴ ┴
930 ∀n (l:list α), (l.modify_nth_tail f n).modify_nth_tail g (m + n) =
id ┴ └──┘ ┴ ┴└──────────────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └──────────────┘ └─────────────┘ ┴ ┴
typ ┴ └──┘ ┴ ┴└──────────────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ ┴
doc └──────────────┘ └─────────────┘
931 l.modify_nth_tail (λl, (f l).modify_nth_tail g m) n
id ┴└──────────────┘ ┴ ┴ ┴ └─────────────┘ ┴ ┴ ┴
src └──────────────┘ └─────────────┘
typ ┴└──────────────┘ ┴ ┴ ┴ └─────────────┘ ┴ ┴ ┴
doc └──────────────┘ └─────────────┘
932 | 0 l := rfl
id └─┘
src └─┘
typ └─┘
933 | (n+1) [] := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
934 | (n+1) (a::l) := congr_arg (list.cons a) (modify_nth_tail_modify_nth_tail n l)
id ┴┴ ┴└┘┴ └───────┘ └───────┘ └─────────────────────────────┘
src ┴ └┘ └───────┘ └───────┘
typ ┴┴ ┴└┘┴ └───────┘ └───────┘ └─────────────────────────────┘
935
936 lemma modify_nth_tail_modify_nth_tail_le
937 {f g : list α → list α} (m n : ℕ) (l : list α) (h : n ≤ m) :
id └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ └──┘ ┴ └──┘ ┴
typ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
938 (l.modify_nth_tail f n).modify_nth_tail g m =
id ┴└──────────────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴
src └──────────────┘ └─────────────┘ ┴
typ ┴└──────────────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴
doc └──────────────┘ └─────────────┘
939 l.modify_nth_tail (λl, (f l).modify_nth_tail g (m - n)) n :=
id ┴└──────────────┘ ┴ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ ┴
src └──────────────┘ └─────────────┘ ┴
typ ┴└──────────────┘ ┴ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ ┴
doc └──────────────┘ └─────────────┘
940 begin
st └─────
941 rcases le_iff_exists_add.1 h with ⟨m, rfl⟩,
id └───────────────┘ ┴
src └─────┘└───────────────┘└─┘ └────────────┘
typ └─────┘└───────────────┘└─┘┴└────────────┘
doc └─────┘ └─┘ └────────────┘
txt └─────┘ └─┘ └────────────┘
par └─────┘ └─┘ └────────────┘
pid ┴ └─┘ └────────────┘
st ───────────────────────────────────────────┘└─
942 rw [nat.add_sub_cancel_left, add_comm, modify_nth_tail_modify_nth_tail]
id └─────────────────────┘ └──────┘ └─────────────────────────────┘
src └──┘└─────────────────────┘└┘└──────┘└┘└─────────────────────────────┘└┘
typ └──┘└─────────────────────┘└┘└──────┘└┘└─────────────────────────────┘└┘
doc └──┘ └┘ └┘ └┘
txt └──┘ └┘ └┘ └┘
par └──┘ └┘ └┘ └┘
pid └┘ └┘ └┘ ┴┴
st ────────────────────────────┘└────────┘└───────────────────────────────┘┴┴
943 end
st └─┘
944
945 lemma modify_nth_tail_modify_nth_tail_same {f g : list α → list α} (n : ℕ) (l:list α) :
id └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘ ┴ └──┘
typ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴
946 (l.modify_nth_tail f n).modify_nth_tail g n = l.modify_nth_tail (g ∘ f) n :=
id ┴└──────────────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴└──────────────┘ ┴ ┴ ┴ ┴
src └──────────────┘ └─────────────┘ ┴ └──────────────┘ ┴
typ ┴└──────────────┘ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴└──────────────┘ ┴ ┴ ┴ ┴
doc └──────────────┘ └─────────────┘ └──────────────┘
947 by rw [modify_nth_tail_modify_nth_tail_le n n l (le_refl n), nat.sub_self]; refl
id └────────────────────────────────┘ ┴ └─────┘ ┴ └──────────┘
src └──┘└────────────────────────────────┘┴ ┴ ┴ ┴ └─────┘┴ └─┘└──────────┘┴ └────
typ └──┘└────────────────────────────────┘┴ ┴ ┴┴┴ └─────┘┴┴└─┘└──────────┘┴ └────
doc └──┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └────
txt └──┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └────
par └──┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └────
pid └┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └
st └───────────────────────────────────────────────────────┘└────────────┘┴└──────
948
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
949 lemma modify_nth_tail_id :
950 ∀n (l:list α), l.modify_nth_tail id n = l
id ┴ └──┘ ┴ ┴└──────────────┘ └┘ ┴ ┴ ┴
src └──┘ └──────────────┘ └┘ ┴
typ ┴ └──┘ ┴ ┴└──────────────┘ └┘ ┴ ┴ ┴
doc └──────────────┘
951 | 0 l := rfl
id └─┘
src └─┘
typ └─┘
952 | (n+1) [] := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
953 | (n+1) (a::l) := congr_arg (list.cons a) (modify_nth_tail_id n l)
id ┴┴ ┴└┘┴ └───────┘ └───────┘ └────────────────┘
src ┴ └┘ └───────┘ └───────┘
typ ┴┴ ┴└┘┴ └───────┘ └───────┘ └────────────────┘
954
955 theorem remove_nth_eq_nth_tail : ∀ n (l : list α), remove_nth l n = modify_nth_tail tail n l
id ┴ └──┘ ┴ └────────┘ ┴ ┴ ┴ └─────────────┘ └──┘ ┴ ┴
src └──┘ └────────┘ ┴ └─────────────┘ └──┘
typ ┴ └──┘ ┴ └────────┘ ┴ ┴ ┴ └─────────────┘ └──┘ ┴ ┴
doc └─────────────┘
956 | 0 l := by cases l; refl
id ┴
src └────┘ └───┘
typ └────┘┴ └───┘
doc └────┘ └───┘
txt └────┘ └───┘
par └────┘ └───┘
pid ┴ ┴
st └─────────────┘
957 | (n+1) [] := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
958 | (n+1) (a::l) := congr_arg (cons _) (remove_nth_eq_nth_tail _ _)
id ┴ └┘ └───────┘ └──┘ └────────────────────┘
src ┴ └┘ └───────┘ └──┘
typ ┴ └┘ └───────┘ └──┘ └────────────────────┘
959
960 theorem update_nth_eq_modify_nth (a : α) : ∀ n (l : list α),
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
961 update_nth l n a = modify_nth (λ _, a) n l
id └────────┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
src └────────┘ ┴ └────────┘
typ └────────┘ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
doc └────────┘
962 | 0 l := by cases l; refl
id ┴
src └────┘ └───┘
typ └────┘┴ └───┘
doc └────┘ └───┘
txt └────┘ └───┘
par └────┘ └───┘
pid ┴ ┴
st └─────────────┘
963 | (n+1) [] := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
964 | (n+1) (b::l) := congr_arg (cons _) (update_nth_eq_modify_nth _ _)
id ┴ └┘ └───────┘ └──┘ └──────────────────────┘
src ┴ └┘ └───────┘ └──┘
typ ┴ └┘ └───────┘ └──┘ └──────────────────────┘
965
966 theorem modify_nth_eq_update_nth (f : α → α) : ∀ n (l : list α),
id ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ └──┘ ┴
967 modify_nth f n l = ((λ a, update_nth l n (f a)) <$> nth l n).get_or_else l
id └────────┘ ┴ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ └─────────┘ ┴
src └────────┘ ┴ └────────┘ └─┘ └─┘ └─────────┘
typ └────────┘ ┴ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ └─────────┘ ┴
doc └────────┘
968 | 0 l := by cases l; refl
id ┴
src └────┘ └───┘
typ └────┘┴ └───┘
doc └────┘ └───┘
txt └────┘ └───┘
par └────┘ └───┘
pid ┴ ┴
st └─────────────┘
969 | (n+1) [] := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
970 | (n+1) (b::l) := (congr_arg (cons b)
id ┴┴ ┴└┘┴ └───────┘ └──┘
src ┴ └┘ └───────┘ └──┘
typ ┴┴ ┴└┘┴ └───────┘ └──┘
971 (modify_nth_eq_update_nth n l)).trans $ by cases nth l n; refl
id └──────────────────────┘ └───┘ └─┘ ┴ ┴
src └───┘ └────┘└─┘┴ ┴ └────
typ └──────────────────────┘ └───┘ └────┘└─┘┴┴┴┴ └────
doc └────┘ ┴ ┴ └────
txt └────┘ ┴ ┴ └────
par └────┘ ┴ ┴ └────
pid ┴ ┴ ┴ └
st └────────────────────
972
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
973 theorem nth_modify_nth (f : α → α) : ∀ n (l : list α) m,
id ┴ ┴ ┴ └──┘ ┴ ┴
src └──┘
typ ┴ ┴ ┴ └──┘ ┴ ┴
974 nth (modify_nth f n l) m = (λ a, if n = m then f a else a) <$> nth l m
id └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
src └─┘ └────────┘ ┴ ┴ └─┘ └─┘
typ └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
doc └────────┘
975 | n l 0 := by cases l; cases n; refl
id ┴ ┴
src └────┘ └────┘ └───┘
typ └────┘┴ └────┘┴ └───┘
doc └────┘ └────┘ └───┘
txt └────┘ └────┘ └───┘
par └────┘ └────┘ └───┘
pid ┴ ┴ ┴
st └──────────────────────┘
976 | n [] (m+1) := by cases n; refl
id └┘ ┴ ┴
src └┘ ┴ └────┘ └───┘
typ └┘ ┴ └────┘┴ └───┘
doc └────┘ └───┘
txt └────┘ └───┘
par └────┘ └───┘
pid ┴ ┴
st └─────────────┘
977 | 0 (a::l) (m+1) := by cases nth l m; refl
id └┘ ┴ └─┘ ┴ ┴
src └┘ ┴ └────┘└─┘┴ ┴ └───┘
typ └┘ ┴ └────┘└─┘┴┴┴┴ └───┘
doc └────┘ ┴ ┴ └───┘
txt └────┘ ┴ ┴ └───┘
par └────┘ ┴ ┴ └───┘
pid ┴ ┴ ┴ ┴
st └───────────────────┘
978 | (n+1) (a::l) (m+1) := (nth_modify_nth n l m).trans $
id ┴┴ └┘┴ ┴┴ └────────────┘ └───┘
src ┴ └┘ ┴ └───┘
typ ┴┴ └┘┴ ┴┴ └────────────┘ └───┘
979 by cases nth l m with b; by_cases n = m;
id └─┘ ┴ ┴ ┴ ┴ ┴
src └────┘└─┘┴ ┴ └─────┘ └───────┘ ┴┴┴
typ └────┘└─┘┴┴┴┴└─────┘ └───────┘┴┴┴┴┴
doc └────┘ ┴ ┴ └─────┘ └───────┘ ┴ ┴
txt └────┘ ┴ ┴ └─────┘ └───────┘ ┴ ┴
par └────┘ ┴ ┴ └─────┘ └───────┘ ┴ ┴
pid ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
st └──────────────────────────────────────
980 simp only [h, if_pos, if_true, if_false, option.map_none, option.map_some, mt succ_inj, not_false_iff]
id ┴ └────┘ └─────┘ └──────┘ └─────────────┘ └─────────────┘ └┘ └──────┘ └───────────┘
src └─────────┘ └┘└────┘└┘└─────┘└┘└──────┘└┘└─────────────┘└┘└─────────────┘└┘└┘┴└──────┘└┘└───────────┘└─
typ └─────────┘┴└┘└────┘└┘└─────┘└┘└──────┘└┘└─────────────┘└┘└─────────────┘└┘└┘┴└──────┘└┘└───────────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └┘ ┴└
st ─────────────────────────────────────────────────────────────────────────────────────────────────────────
981
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
982 theorem modify_nth_tail_length (f : list α → list α) (H : ∀ l, length (f l) = length l) :
id └──┘ ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴
src └──┘ └──┘ └────┘ ┴ └────┘
typ └──┘ ┴ └──┘ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴
983 ∀ n l, length (modify_nth_tail f n l) = length l
id ┴ ┴ └────┘ └─────────────┘ ┴ ┴ ┴ ┴ └────┘ ┴
src └────┘ └─────────────┘ ┴ └────┘
typ ┴ ┴ └────┘ └─────────────┘ ┴ ┴ ┴ ┴ └────┘ ┴
doc └─────────────┘
984 | 0 l := H _
id ┴
typ ┴
985 | (n+1) [] := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
986 | (n+1) (a::l) := @congr_arg _ _ _ _ (+1) (modify_nth_tail_length _ _)
id ┴ └┘ └───────┘ ┴ └────────────────────┘
src ┴ └┘ └───────┘ ┴
typ ┴ └┘ └───────┘ ┴ └────────────────────┘
987
988 @[simp] theorem modify_nth_length (f : α → α) :
id ┴ ┴
typ ┴ ┴
doc └──┘
989 ∀ n l, length (modify_nth f n l) = length l :=
id ┴ ┴ └────┘ └────────┘ ┴ ┴ ┴ ┴ └────┘ ┴
src └────┘ └────────┘ ┴ └────┘
typ ┴ ┴ └────┘ └────────┘ ┴ ┴ ┴ ┴ └────┘ ┴
doc └────────┘
990 modify_nth_tail_length _ (λ l, by cases l; refl)
id └────────────────────┘ ┴ ┴
src └────────────────────┘ └────┘ └──┘
typ └────────────────────┘ ┴ └────┘┴ └──┘
doc └────┘ └──┘
txt └────┘ └──┘
par └────┘ └──┘
pid ┴
st └────────────┘
991
992 @[simp] theorem update_nth_length (l : list α) (n) (a : α) :
id └──┘ ┴ ┴
src └──┘
typ └──┘ ┴ ┴
doc └──┘
993 length (update_nth l n a) = length l :=
id └────┘ └────────┘ ┴ ┴ ┴ ┴ └────┘ ┴
src └────┘ └────────┘ ┴ └────┘
typ └────┘ └────────┘ ┴ ┴ ┴ ┴ └────┘ ┴
994 by simp only [update_nth_eq_modify_nth, modify_nth_length]
id └──────────────────────┘ └───────────────┘
src └─────────┘└──────────────────────┘└┘└───────────────┘└─
typ └─────────┘└──────────────────────┘└┘└───────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────────────────────────────────
995
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
996 @[simp] theorem nth_modify_nth_eq (f : α → α) (n) (l : list α) :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
doc └──┘
997 nth (modify_nth f n l) n = f <$> nth l n :=
id └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
src └─┘ └────────┘ ┴ └─┘ └─┘
typ └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
doc └────────┘
998 by simp only [nth_modify_nth, if_pos]
id └────────────┘ └────┘
src └─────────┘└────────────┘└┘└────┘└─
typ └─────────┘└────────────┘└┘└────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └───────────────────────────────────
999
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1000 @[simp] theorem nth_modify_nth_ne (f : α → α) {m n} (l : list α) (h : m ≠ n) :
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘
1001 nth (modify_nth f m l) n = nth l n :=
id └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src └─┘ └────────┘ ┴ └─┘
typ └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
doc └────────┘
1002 by simp only [nth_modify_nth, if_neg h, id_map']
id └────────────┘ └────┘ ┴ └─────┘
src └─────────┘└────────────┘└┘└────┘┴ └┘└─────┘└─
typ └─────────┘└────────────┘└┘└────┘┴┴└┘└─────┘└─
doc └─────────┘ └┘ ┴ └┘ └─
txt └─────────┘ └┘ ┴ └┘ └─
par └─────────┘ └┘ ┴ └┘ └─
pid ┴└──┘└┘ └┘ ┴ └┘ ┴└
st └──────────────────────────────────────────────
1003
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1004 theorem nth_update_nth_eq (a : α) (n) (l : list α) :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
1005 nth (update_nth l n a) n = (λ _, a) <$> nth l n :=
id └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
src └─┘ └────────┘ ┴ └─┘ └─┘
typ └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
1006 by simp only [update_nth_eq_modify_nth, nth_modify_nth_eq]
id └──────────────────────┘ └───────────────┘
src └─────────┘└──────────────────────┘└┘└───────────────┘└─
typ └─────────┘└──────────────────────┘└┘└───────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────────────────────────────────
1007
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1008 theorem nth_update_nth_of_lt (a : α) {n} {l : list α} (h : n < length l) :
id ┴ └──┘ ┴ ┴ ┴ └────┘ ┴
src └──┘ ┴ └────┘
typ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴
1009 nth (update_nth l n a) n = some a :=
id └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └─┘ └────────┘ ┴ └──┘
typ └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
1010 by rw [nth_update_nth_eq, nth_le_nth h]; refl
id └───────────────┘ └────────┘ ┴
src └──┘└───────────────┘└┘└────────┘┴ ┴ └────
typ └──┘└───────────────┘└┘└────────┘┴┴┴ └────
doc └──┘ └┘ ┴ ┴ └────
txt └──┘ └┘ ┴ ┴ └────
par └──┘ └┘ ┴ ┴ └────
pid └┘ └┘ ┴ ┴ └
st └────────────────────┘└────────────┘┴└──────
1011
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1012 theorem nth_update_nth_ne (a : α) {m n} (l : list α) (h : m ≠ n) :
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴
1013 nth (update_nth l m a) n = nth l n :=
id └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src └─┘ └────────┘ ┴ └─┘
typ └─┘ └────────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
1014 by simp only [update_nth_eq_modify_nth, nth_modify_nth_ne _ _ h]
id └──────────────────────┘ └───────────────┘ ┴
src └─────────┘└──────────────────────┘└┘└───────────────┘└───┘ └─
typ └─────────┘└──────────────────────┘└┘└───────────────┘└───┘┴└─
doc └─────────┘ └┘ └───┘ └─
txt └─────────┘ └┘ └───┘ └─
par └─────────┘ └┘ └───┘ └─
pid ┴└──┘└┘ └┘ └───┘ ┴└
st └──────────────────────────────────────────────────────────────
1015
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1016 @[simp] lemma nth_le_update_nth_eq (l : list α) (i : ℕ) (a : α)
id └──┘ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴
doc └──┘
1017 (h : i < (l.update_nth i a).length) : (l.update_nth i a).nth_le i h = a :=
id ┴ ┴ ┴└─────────┘ ┴ ┴ └────┘ ┴└─────────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
src ┴ └─────────┘ └────┘ └─────────┘ └────┘ ┴
typ ┴ ┴ ┴└─────────┘ ┴ ┴ └────┘ ┴└─────────┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
1018 by rw [← option.some_inj, ← nth_le_nth, nth_update_nth_eq, nth_le_nth]; simp * at *
id └─────────────┘ └────────┘ └───────────────┘ └────────┘
src └────┘└─────────────┘└──┘└────────┘└┘└───────────────┘└┘└────────┘┴ └───────────
typ └────┘└─────────────┘└──┘└────────┘└┘└───────────────┘└┘└────────┘┴ └───────────
doc └────┘ └──┘ └┘ └┘ ┴ └───────────
txt └────┘ └──┘ └┘ └┘ ┴ └───────────
par └────┘ └──┘ └┘ └┘ ┴ └───────────
pid └──┘ └──┘ └┘ └┘ ┴ ┴┴┴└──┘└
st └────────────────────┘└────────────┘└─────────────────┘└──────────┘┴└─────────────
1019
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1020 @[simp] lemma nth_le_update_nth_of_ne {l : list α} {i j : ℕ} (h : i ≠ j) (a : α)
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘
1021 (hj : j < (l.update_nth i a).length) :
id ┴ ┴ ┴└─────────┘ ┴ ┴ └────┘
src ┴ └─────────┘ └────┘
typ ┴ ┴ ┴└─────────┘ ┴ ┴ └────┘
1022 (l.update_nth i a).nth_le j hj = l.nth_le j (by simpa using hj) :=
id ┴└─────────┘ ┴ ┴ └────┘ ┴ └┘ ┴ ┴└─────┘ ┴ └┘
src └─────────┘ └────┘ ┴ └─────┘ └──────────┘
typ ┴└─────────┘ ┴ ┴ └────┘ ┴ └┘ ┴ ┴└─────┘ ┴ └──────────┘└┘
doc └──────────┘
txt └──────────┘
par └──────────┘
pid ┴└────┘
st └─────────────┘
1023 by rw [← option.some_inj, ← list.nth_le_nth, list.nth_update_nth_ne _ _ h, list.nth_le_nth]
id └─────────────┘ └─────────────┘ └────────────────────┘ ┴ └─────────────┘
src └────┘└─────────────┘└──┘└─────────────┘└┘└────────────────────┘└───┘ └┘└─────────────┘└─
typ └────┘└─────────────┘└──┘└─────────────┘└┘└────────────────────┘└───┘┴└┘└─────────────┘└─
doc └────┘ └──┘ └┘ └───┘ └┘ └─
txt └────┘ └──┘ └┘ └───┘ └┘ └─
par └────┘ └──┘ └┘ └───┘ └┘ └─
pid └──┘ └──┘ └┘ └───┘ └┘ ┴└
st └────────────────────┘└─────────────────┘└────────────────────────────┘└───────────────┘┴└
1024
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1025 lemma mem_or_eq_of_mem_update_nth : ∀ {l : list α} {n : ℕ} {a b : α}
id ┴ └──┘ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴
1026 (h : a ∈ l.update_nth n b), a ∈ l ∨ a = b
id ┴ ┴ ┴└─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └─────────┘ ┴ ┴ ┴
typ ┴ ┴ ┴└─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1027 | [] n a b h := false.elim h
id └┘ ┴ └────────┘
src └┘ └────────┘
typ └┘ ┴ └────────┘
1028 | (c::l) 0 a b h := ((mem_cons_iff _ _ _).1 h).elim
id └┘ ┴ └──────────┘ ┴ └──┘
src └┘ └──────────┘ ┴ └──┘
typ └┘ ┴ └──────────┘ ┴ └──┘
1029 or.inr (or.inl ∘ mem_cons_of_mem _)
id └────┘ └────┘ ┴ └─────────────┘
src └────┘ └────┘ ┴ └─────────────┘
typ └────┘ └────┘ ┴ └─────────────┘
1030 | (c::l) (n+1) a b h := ((mem_cons_iff _ _ _).1 h).elim
id └┘ ┴ ┴ └──────────┘ ┴ └──┘
src └┘ ┴ └──────────┘ ┴ └──┘
typ └┘ ┴ ┴ └──────────┘ ┴ └──┘
1031 (λ h, h ▸ or.inl (mem_cons_self _ _))
id ┴ ┴ ┴ └────┘ └───────────┘
src ┴ └────┘ └───────────┘
typ ┴ ┴ ┴ └────┘ └───────────┘
1032 (λ h, (mem_or_eq_of_mem_update_nth h).elim
id ┴ └─────────────────────────┘ ┴ └──┘
src └──┘
typ ┴ └─────────────────────────┘ ┴ └──┘
1033 (or.inl ∘ mem_cons_of_mem _) or.inr)
id └────┘ ┴ └─────────────┘ └────┘
src └────┘ ┴ └─────────────┘ └────┘
typ └────┘ ┴ └─────────────┘ └────┘
1034
1035 section insert_nth
1036 variable {a : α}
1037
1038 @[simp] lemma insert_nth_nil (a : α) : insert_nth 0 a [] = [a] := rfl
id ┴ └────────┘ ┴ └┘ ┴ ┴┴┴ └─┘
src └────────┘ └┘ ┴ ┴ ┴ └─┘
typ ┴ └────────┘ ┴ └┘ ┴ ┴┴┴ └─┘
doc └──┘
1039
1040 lemma length_insert_nth : ∀n as, n ≤ length as → length (insert_nth n a as) = length as + 1
id ┴ └┘ ┴ ┴ └────┘ └┘ └────┘ └────────┘ ┴ ┴ └┘ ┴ └────┘ └┘ ┴
src ┴ └────┘ └────┘ └────────┘ ┴ └────┘ ┴
typ ┴ └┘ ┴ ┴ └────┘ └┘ └────┘ └────────┘ ┴ ┴ └┘ ┴ └────┘ └┘ ┴
1041 | 0 as h := rfl
id └─┘
src └─┘
typ └─┘
1042 | (n+1) [] h := (nat.not_succ_le_zero _ h).elim
id ┴ └┘ ┴ └──────────────────┘ └──┘
src ┴ └┘ └──────────────────┘ └──┘
typ ┴ └┘ ┴ └──────────────────┘ └──┘
1043 | (n+1) (a'::as) h := congr_arg nat.succ $ length_insert_nth n as (nat.le_of_succ_le_succ h)
id ┴┴ └┘└┘ ┴ └───────┘ └──────┘ └───────────────┘ └────────────────────┘
src ┴ └┘ └───────┘ └──────┘ └────────────────────┘
typ ┴┴ └┘└┘ ┴ └───────┘ └──────┘ └───────────────┘ └────────────────────┘
1044
1045 lemma remove_nth_insert_nth (n:ℕ) (l : list α) : (l.insert_nth n a).remove_nth n = l :=
id ┴ └──┘ ┴ ┴└─────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴
src ┴ └──┘ └─────────┘ └────────┘ ┴
typ ┴ └──┘ ┴ ┴└─────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴
1046 by rw [remove_nth_eq_nth_tail, insert_nth, modify_nth_tail_modify_nth_tail_same];
id └────────────────────┘ └────────┘ └──────────────────────────────────┘
src └──┘└────────────────────┘└┘└────────┘└┘└──────────────────────────────────┘┴
typ └──┘└────────────────────┘└┘└────────┘└┘└──────────────────────────────────┘┴
doc └──┘ └┘ └┘ ┴
txt └──┘ └┘ └┘ ┴
par └──┘ └┘ └┘ ┴
pid └┘ └┘ └┘ ┴
st └─────────────────────────┘└──────────┘└────────────────────────────────────┘┴└─
1047 from modify_nth_tail_id _ _
id └────────────────┘
src └───┘└────────────────┘└────
typ └───┘└────────────────┘└────
doc └───┘ └────
txt └───┘ └────
par └───┘ └────
pid └───┘ └──┘└
st ────────────────────────────
1048
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1049 lemma insert_nth_remove_nth_of_ge : ∀n m as, n < length as → m ≥ n →
id ┴ ┴ └┘ ┴ ┴ └────┘ └┘ ┴ ┴ ┴
src ┴ └────┘ ┴
typ ┴ ┴ └┘ ┴ ┴ └────┘ └┘ ┴ ┴ ┴
1050 insert_nth m a (as.remove_nth n) = (as.insert_nth (m + 1) a).remove_nth n
id └────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ ┴ └────────┘ ┴
src └────────┘ └─────────┘ ┴ └─────────┘ ┴ └────────┘
typ └────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ ┴ └────────┘ ┴
1051 | 0 0 [] has _ := (lt_irrefl _ has).elim
id └┘ └─┘ └───────┘ └──┘
src └┘ └───────┘ └──┘
typ └┘ └─┘ └───────┘ └──┘
1052 | 0 0 (a::as) has hmn := by simp [remove_nth, insert_nth]
id └┘ └────────┘ └────────┘
src └┘ └────┘└────────┘└┘└────────┘└┘
typ └┘ └────┘└────────┘└┘└────────┘└┘
doc └────┘ └┘ └┘
txt └────┘ └┘ └┘
par └────┘ └┘ └┘
pid ┴┴ └┘ ┴┴
st └─────────────────────────────┘
1053 | 0 (m+1) (a::as) has hmn := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
1054 | (n+1) (m+1) (a::as) has hmn :=
id ┴┴ ┴┴ ┴└┘└┘ └─┘ └─┘
src ┴ ┴ └┘
typ ┴┴ ┴┴ ┴└┘└┘ └─┘ └─┘
1055 congr_arg (cons a) $
id └───────┘ └──┘
src └───────┘ └──┘
typ └───────┘ └──┘
1056 insert_nth_remove_nth_of_ge n m as (nat.lt_of_succ_lt_succ has) (nat.le_of_succ_le_succ hmn)
id └─────────────────────────┘ └────────────────────┘ └────────────────────┘
src └────────────────────┘ └────────────────────┘
typ └─────────────────────────┘ └────────────────────┘ └────────────────────┘
1057
1058 lemma insert_nth_remove_nth_of_le : ∀n m as, n < length as → m ≤ n →
id ┴ ┴ └┘ ┴ ┴ └────┘ └┘ ┴ ┴ ┴
src ┴ └────┘ ┴
typ ┴ ┴ └┘ ┴ ┴ └────┘ └┘ ┴ ┴ ┴
1059 insert_nth m a (as.remove_nth n) = (as.insert_nth m a).remove_nth (n + 1)
id └────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ └────────┘ ┴ ┴
src └────────┘ └─────────┘ ┴ └─────────┘ └────────┘ ┴
typ └────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ └┘└─────────┘ ┴ ┴ └────────┘ ┴ ┴
1060 | n 0 (a :: as) has hmn := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1061 | (n + 1) (m + 1) (a :: as) has hmn :=
id ┴ ┴ ┴ ┴ ┴ └┘ └┘ └─┘ └─┘
src ┴ ┴ └┘
typ ┴ ┴ ┴ ┴ ┴ └┘ └┘ └─┘ └─┘
1062 congr_arg (cons a) $
id └───────┘ └──┘
src └───────┘ └──┘
typ └───────┘ └──┘
1063 insert_nth_remove_nth_of_le n m as (nat.lt_of_succ_lt_succ has) (nat.le_of_succ_le_succ hmn)
id └─────────────────────────┘ └────────────────────┘ └────────────────────┘
src └────────────────────┘ └────────────────────┘
typ └─────────────────────────┘ └────────────────────┘ └────────────────────┘
1064
1065 lemma insert_nth_comm (a b : α) :
id ┴
typ ┴
1066 ∀(i j : ℕ) (l : list α) (h : i ≤ j) (hj : j ≤ length l),
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴
src ┴ └──┘ ┴ ┴ └────┘
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴
1067 (l.insert_nth i a).insert_nth (j + 1) b = (l.insert_nth j b).insert_nth i a
id ┴└─────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴└─────────┘ ┴ ┴ └────────┘ ┴ ┴
src └─────────┘ └────────┘ ┴ ┴ └─────────┘ └────────┘
typ ┴└─────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴└─────────┘ ┴ ┴ └────────┘ ┴ ┴
1068 | 0 j l := by simp [insert_nth]
id └────────┘
src └────┘└────────┘└┘
typ └────┘└────────┘└┘
doc └────┘ └┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st └─────────────────┘
1069 | (i + 1) 0 l := assume h, (nat.not_lt_zero _ h).elim
id ┴ ┴ └─────────────┘ ┴ └──┘
src ┴ └─────────────┘ └──┘
typ ┴ ┴ └─────────────┘ ┴ └──┘
1070 | (i + 1) (j+1) [] := by simp
id ┴ ┴ └┘
src ┴ ┴ └┘ └───┘
typ ┴ ┴ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
1071 | (i + 1) (j+1) (c::l) :=
id ┴ ┴ └┘
src ┴ ┴ └┘
typ ┴ ┴ └┘
1072 assume h₀ h₁,
id └┘ └┘
typ └┘ └┘
1073 by simp [insert_nth]; exact insert_nth_comm i j l (nat.le_of_succ_le_succ h₀) (nat.le_of_succ_le_succ h₁)
id └────────┘ └─────────────┘ ┴ ┴ ┴ └┘ └────────────────────┘ └┘
src └────┘└────────┘┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────────────────────┘┴ └─
typ └────┘└────────┘┴ └────┘└─────────────┘┴┴┴┴┴┴┴ ┴└┘└┘ └────────────────────┘┴└┘└─
doc └────┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └─
txt └────┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └─
par └────┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └─
pid ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴└
st └───────────────────────────────────────────────────────────────────────────────────────────────────────
1074
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1075 lemma mem_insert_nth {a b : α} : ∀ {n : ℕ} {l : list α} (hi : n ≤ l.length),
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴└─────┘
src ┴ └──┘ ┴ └─────┘
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴└─────┘
1076 a ∈ l.insert_nth n b ↔ a = b ∨ a ∈ l
id ┴ ┴ ┴└─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └─────────┘ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴└─────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1077 | 0 as h := iff.rfl
id └─────┘
src └─────┘
typ └─────┘
1078 | (n+1) [] h := (nat.not_succ_le_zero _ h).elim
id ┴ └┘ ┴ └──────────────────┘ └──┘
src ┴ └┘ └──────────────────┘ └──┘
typ ┴ └┘ ┴ └──────────────────┘ └──┘
1079 | (n+1) (a'::as) h := begin
id ┴ └┘
src ┴ └┘
typ ┴ └┘
st └─────
1080 dsimp [list.insert_nth],
id └─────────────┘
src └─────┘└─────────────┘┴
typ └─────┘└─────────────┘┴
doc └─────┘ ┴
txt └─────┘ ┴
par └─────┘ ┴
pid ┴┴ ┴
st ────────────────────────┘└─
1081 erw [list.mem_cons_iff, mem_insert_nth (nat.le_of_succ_le_succ h), list.mem_cons_iff,
id └───────────────┘ └────────────┘ └────────────────────┘ ┴ └───────────────┘
src └───┘└───────────────┘└┘ ┴ └────────────────────┘┴ └─┘└───────────────┘└─
typ └───┘└───────────────┘└┘└────────────┘┴ └────────────────────┘┴┴└─┘└───────────────┘└─
doc └───┘ └┘ ┴ ┴ └─┘ └─
txt └───┘ └┘ ┴ ┴ └─┘ └─
par └───┘ └┘ ┴ ┴ └─┘ └─
pid └┘ └┘ ┴ ┴ └─┘ └─
st ───────────────────────┘└─────────────────────────────────────────┘└─────────────────┘└─
1082 ← or.assoc, or_comm (a = a'), or.assoc]
id └──────┘ └─────┘ ┴ ┴ └┘ └──────┘
src ─────┘└──────┘└┘└─────┘┴ ┴┴┴ └─┘└──────┘└┘
typ ─────┘└──────┘└┘└─────┘┴ ┴┴┴┴└┘└─┘└──────┘└┘
doc ─────┘ └┘ ┴ ┴ ┴ └─┘ └┘
txt ─────┘ └┘ ┴ ┴ ┴ └─┘ └┘
par ─────┘ └┘ ┴ ┴ ┴ └─┘ └┘
pid ─────┘ └┘ ┴ ┴ ┴ └─┘ ┴┴
st ─────────────┘└────────────────┘└────────┘┴┴
1083 end
st └─┘
1084
1085 end insert_nth
1086
1087 /- map -/
1088
1089 lemma map_congr {f g : α → β} : ∀ {l : list α}, (∀ x ∈ l, f x = g x) → map f l = map g l
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ ┴ └─┘ ┴ └─┘
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
1090 | [] _ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1091 | (a::l) h := let ⟨h₁, h₂⟩ := forall_mem_cons.1 h in
id └┘ ┴ └─┘ └─────────────┘┴
src └┘ └─────────────┘┴
typ └┘ ┴ └─┘ └─────────────┘┴
1092 by rw [map, map, h₁, map_congr h₂]
id └─┘ └─┘ └┘ └───────┘ └┘
src └──┘└─┘└┘└─┘└┘ └┘ ┴ └─
typ └──┘└─┘└┘└─┘└┘└┘└┘└───────┘┴└┘└─
doc └──┘ └┘ └┘ └┘ ┴ └─
txt └──┘ └┘ └┘ └┘ ┴ └─
par └──┘ └┘ └┘ └┘ ┴ └─
pid └┘ └┘ └┘ └┘ ┴ ┴└
st └──────┘└───┘└──┘└────────────┘┴└
1093
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1094 lemma map_eq_map_iff {f g : α → β} {l : list α} : map f l = map g l ↔ (∀ x ∈ l, f x = g x) :=
id ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └─┘ ┴ └─┘ ┴ ┴
typ ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1095 begin
st └─────
1096 refine ⟨_, map_congr⟩, intros h x hx,
id └───────┘
src └─────┘ └─┘└───────┘┴ └───────────┘
typ └─────┘ └─┘└───────┘┴ └───────────┘
doc └─────┘ └─┘ ┴ └───────────┘
txt └─────┘ └─┘ ┴ └───────────┘
par └─────┘ └─┘ ┴ └───────────┘
pid ┴ └─┘ ┴ └─────┘
st ──────────────────────┘└─────────────┘└─
1097 rw [mem_iff_nth_le] at hx, rcases hx with ⟨n, hn, rfl⟩,
id └────────────┘ └┘
src └──┘└────────────┘└─────┘ └─────┘ └────────────────┘
typ └──┘└────────────┘└─────┘ └─────┘└┘└────────────────┘
doc └──┘ └─────┘ └─────┘ └────────────────┘
txt └──┘ └─────┘ └─────┘ └────────────────┘
par └──┘ └─────┘ └─────┘ └────────────────┘
pid └┘ ┴└────┘ ┴ └────────────────┘
st ───────────────────┘┴└────┘└───────────────────────────┘└─
1098 rw [nth_le_map_rev f, nth_le_map_rev g], congr, exact h
id └────────────┘ ┴ └────────────┘ ┴ ┴
src └──┘└────────────┘┴ └┘└────────────┘┴ ┴ └───┘ └────┘ ┴
typ └──┘└────────────┘┴┴└┘└────────────┘┴┴┴ └───┘ └────┘┴┴
doc └──┘└────────────┘┴ └┘└────────────┘┴ ┴ └────┘ ┴
txt └──┘ ┴ └┘ ┴ ┴ └───┘ └────┘ ┴
par └──┘ ┴ └┘ ┴ ┴ └───┘ └────┘ ┴
pid └┘ ┴ └┘ ┴ ┴ ┴ ┴
st ─────────────────────┘└────────────────┘└──────┘└────────┘
1099 end
st └─┘
1100
1101 theorem map_concat (f : α → β) (a : α) (l : list α) : map f (concat l a) = concat (map f l) (f a) :=
id ┴ ┴ ┴ └──┘ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ └────┘ └─┘ ┴ ┴ ┴ ┴
src └──┘ └─┘ └────┘ ┴ └────┘ └─┘
typ ┴ ┴ ┴ └──┘ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ └────┘ └─┘ ┴ ┴ ┴ ┴
doc └────┘ └────┘
1102 by induction l; [refl, simp only [*, concat_eq_append, cons_append, map, map_append]]; split; refl
id ┴ ┴ └──────────────┘ └─────────┘ └─┘ └────────┘
src └────────┘ ┴└──┘ └────────────┘└──────────────┘└┘└─────────┘└┘└─┘└┘└────────┘┴ └───┘ └────
typ └────────┘┴ ┴└──┘ └────────────┘└──────────────┘└┘└─────────┘└┘└─┘└┘└────────┘┴ └───┘ └────
doc └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴ └───┘ └────
txt └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴ └───┘ └────
par └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ └┘ └┘ └┘ ┴ └
st └────────────────────────────────────────────────────────────────────────────────────────────────
1103
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1104 theorem map_id' {f : α → α} (h : ∀ x, f x = x) (l : list α) : map f l = l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴
src ┴ └──┘ └─┘ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴
1105 by induction l; [refl, simp only [*, map]]; split; refl
id ┴ ┴ └─┘
src └────────┘ ┴└──┘ └────────────┘└─┘┴ └───┘ └────
typ └────────┘┴ ┴└──┘ └────────────┘└─┘┴ └───┘ └────
doc └────────┘ └──┘ └────────────┘ ┴ └───┘ └────
txt └────────┘ └──┘ └────────────┘ ┴ └───┘ └────
par └────────┘ └──┘ └────────────┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ ┴ └
st └─────────────────────────────────────────────────────
1106
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1107 @[simp] theorem foldl_map (g : β → γ) (f : α → γ → α) (a : α) (l : list β) :
id ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1108 foldl f a (map g l) = foldl (λx y, f x (g y)) a l :=
id └───┘ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └───┘ └─┘ ┴ └───┘
typ └───┘ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1109 by revert a; induction l; intros; [refl, simp only [*, map, foldl]]
id ┴ ┴ └─┘ └───┘
src └──────┘ └────────┘ └────┘ ┴└──┘ └────────────┘└─┘└┘└───┘┴
typ └──────┘ └────────┘┴ └────┘ ┴└──┘ └────────────┘└─┘└┘└───┘┴
doc └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
txt └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
par └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
pid └┘ ┴ ┴└──┘└───┘ └┘ ┴
st └───────────────────────────────────────────────────────────────┘
1110
1111 @[simp] theorem foldr_map (g : β → γ) (f : γ → α → α) (a : α) (l : list β) :
id ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1112 foldr f a (map g l) = foldr (f ∘ g) a l :=
id └───┘ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
src └───┘ └─┘ ┴ └───┘ ┴
typ └───┘ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
1113 by revert a; induction l; intros; [refl, simp only [*, map, foldr]]
id ┴ ┴ └─┘ └───┘
src └──────┘ └────────┘ └────┘ ┴└──┘ └────────────┘└─┘└┘└───┘┴
typ └──────┘ └────────┘┴ └────┘ ┴└──┘ └────────────┘└─┘└┘└───┘┴
doc └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
txt └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
par └──────┘ └────────┘ └────┘ └──┘ └────────────┘ └┘ ┴
pid └┘ ┴ ┴└──┘└───┘ └┘ ┴
st └───────────────────────────────────────────────────────────────┘
1114
1115 theorem foldl_hom (l : list γ) (f : α → β) (op : α → γ → α) (op' : β → γ → β) (a : α)
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1116 (h : ∀a x, f (op a x) = op' (f a) x) : foldl op' (f a) l = f (foldl op a l) :=
id ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ └─┘ ┴ ┴ ┴ ┴ ┴ └───┘ └┘ ┴ ┴
src ┴ └───┘ ┴ └───┘
typ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ └─┘ ┴ ┴ ┴ ┴ ┴ └───┘ └┘ ┴ ┴
1117 eq.symm $ by { revert a, induction l; intros; [refl, simp only [*, foldl]] }
id └─────┘ ┴ ┴ └───┘
src └─────┘ └──────┘ └────────┘ └────┘ ┴└──┘ └────────────┘└───┘┴
typ └─────┘ └──────┘ └────────┘┴ └────┘ ┴└──┘ └────────────┘└───┘┴
doc └──────┘ └────────┘ └────┘ └──┘ └────────────┘ ┴
txt └──────┘ └────────┘ └────┘ └──┘ └────────────┘ ┴
par └──────┘ └────────┘ └────┘ └──┘ └────────────┘ ┴
pid └┘ ┴ ┴└──┘└───┘ ┴
st └─────────┘└─────────────────────────────────────────────────┘└─┘
1118
1119 theorem foldr_hom (l : list γ) (f : α → β) (op : γ → α → α) (op' : γ → β → β) (a : α)
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1120 (h : ∀x a, f (op x a) = op' x (f a)) : foldr op' (f a) l = f (foldr op a l) :=
id ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ └─┘ ┴ ┴ ┴ ┴ ┴ └───┘ └┘ ┴ ┴
src ┴ └───┘ ┴ └───┘
typ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ └─┘ ┴ ┴ ┴ ┴ ┴ └───┘ └┘ ┴ ┴
1121 by { revert a, induction l; intros; [refl, simp only [*, foldr]] }
id ┴ ┴ └───┘
src └──────┘ └────────┘ └────┘ ┴└──┘ └────────────┘└───┘┴
typ └──────┘ └────────┘┴ └────┘ ┴└──┘ └────────────┘└───┘┴
doc └──────┘ └────────┘ └────┘ └──┘ └────────────┘ ┴
txt └──────┘ └────────┘ └────┘ └──┘ └────────────┘ ┴
par └──────┘ └────────┘ └────┘ └──┘ └────────────┘ ┴
pid └┘ ┴ ┴└──┘└───┘ ┴
st └─────────┘└─────────────────────────────────────────────────┘└─┘
1122
1123 theorem eq_nil_of_map_eq_nil {f : α → β} {l : list α} (h : map f l = nil) : l = nil :=
id ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘
src └──┘ └─┘ ┴ └─┘ ┴ └─┘
typ ┴ ┴ └──┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘
1124 eq_nil_of_length_eq_zero $ by rw [← length_map f l, h]; refl
id └──────────────────────┘ └────────┘ ┴ ┴ ┴
src └──────────────────────┘ └────┘└────────┘┴ ┴ └┘ ┴ └────
typ └──────────────────────┘ └────┘└────────┘┴┴┴┴└┘┴┴ └────
doc └────┘ ┴ ┴ └┘ ┴ └────
txt └────┘ ┴ ┴ └┘ ┴ └────
par └────┘ ┴ ┴ └┘ ┴ └────
pid └──┘ ┴ ┴ └┘ ┴ └
st └───────────────────┘└─┘┴└──────
1125
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1126 @[simp] theorem map_join (f : α → β) (L : list (list α)) :
id ┴ ┴ └──┘ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ └──┘ ┴
doc └──┘
1127 map f (join L) = join (map (map f) L) :=
id └─┘ ┴ └──┘ ┴ ┴ └──┘ └─┘ └─┘ ┴ ┴
src └─┘ └──┘ ┴ └──┘ └─┘ └─┘
typ └─┘ ┴ └──┘ ┴ ┴ └──┘ └─┘ └─┘ ┴ ┴
1128 by induction L; [refl, simp only [*, join, map, map_append]]
id ┴ ┴ └──┘ └─┘ └────────┘
src └────────┘ ┴└──┘ └────────────┘└──┘└┘└─┘└┘└────────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└──┘└┘└─┘└┘└────────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ ┴
st └────────────────────────────────────────────────────────┘
1129
1130 theorem bind_ret_eq_map (f : α → β) (l : list α) :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
1131 l.bind (list.ret ∘ f) = map f l :=
id ┴└───┘ └──────┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └───┘ └──────┘ ┴ ┴ └─┘
typ ┴└───┘ └──────┘ ┴ ┴ ┴ └─┘ ┴ ┴
1132 by unfold list.bind; induction l; simp only [map, join, list.ret, cons_append, nil_append, *]; split; refl
id ┴ └─┘ └──┘ └──────┘ └─────────┘ └────────┘
src └──────────────┘ └────────┘ └─────────┘└─┘└┘└──┘└┘└──────┘└┘└─────────┘└┘└────────┘└──┘ └───┘ └────
typ └──────────────┘ └────────┘┴ └─────────┘└─┘└┘└──┘└┘└──────┘└┘└─────────┘└┘└────────┘└──┘ └───┘ └────
doc └──────────────┘ └────────┘ └─────────┘ └┘ └┘ └┘ └┘ └──┘ └───┘ └────
txt └──────────────┘ └────────┘ └─────────┘ └┘ └┘ └┘ └┘ └──┘ └───┘ └────
par └──────────────┘ └────────┘ └─────────┘ └┘ └┘ └┘ └┘ └──┘ └───┘ └────
pid └────────┘ ┴ ┴└──┘└┘ └┘ └┘ └┘ └┘ └──┘ └
st └────────────────────────────────────────────────────────────────────────────────────────────────────────
1133
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1134 @[simp] theorem map_eq_map {α β} (f : α → β) (l : list α) : f <$> l = map f l := rfl
id ┴ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ └─┘
src └──┘ └─┘ ┴ └─┘ └─┘
typ ┴ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ └─┘
doc └──┘
1135
1136 @[simp] theorem map_tail (f : α → β) (l) : map f (tail l) = tail (map f l) :=
id ┴ ┴ └─┘ ┴ └──┘ ┴ ┴ └──┘ └─┘ ┴ ┴
src └─┘ └──┘ ┴ └──┘ └─┘
typ ┴ ┴ └─┘ ┴ └──┘ ┴ ┴ └──┘ └─┘ ┴ ┴
doc └──┘
1137 by cases l; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
1138
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1139 @[simp] theorem injective_map_iff {f : α → β} : injective (map f) ↔ injective f :=
id ┴ ┴ └───────┘ └─┘ ┴ ┴ └───────┘ ┴
src └───────┘ └─┘ ┴ └───────┘
typ ┴ ┴ └───────┘ └─┘ ┴ ┴ └───────┘ ┴
doc └──┘
1140 begin
st └─────
1141 split; intros h x y hxy,
src └───┘ └──────────────┘
typ └───┘ └──────────────┘
doc └───┘ └──────────────┘
txt └───┘ └──────────────┘
par └───┘ └──────────────┘
pid └────────┘
st ────────────────────────┘└─
1142 { suffices : [x] = [y], { simpa using this }, apply h, simp [hxy] },
id ┴ ┴ ┴┴┴ └──┘ └─┘
src └─────────┘ ┴┴┴┴ ┴ └──────────┘ ┴ └────┘ └────┘ └┘
typ └─────────┘ ┴ ┴┴┴┴┴┴ └──────────┘└──┘┴ └────┘ └────┘└─┘└┘
doc └─────────┘ ┴ ┴ └──────────┘ ┴ └────┘ └────┘ └┘
txt └─────────┘ ┴ ┴ └──────────┘ ┴ └────┘ └────┘ └┘
par └─────────┘ ┴ ┴ └──────────┘ ┴ └────┘ └────┘ └┘
pid └───────┘└┘ ┴ ┴ ┴└────┘ ┴ ┴ ┴┴ ┴┴
st ───┘└──────────────────┘└──┘└───────────────┘└┘└──────┘└───────────┘└┘└
1143 { induction y generalizing x, simpa using hxy,
id ┴ └─┘
src └────────┘ └─────────────┘ └──────────┘
typ └────────┘┴└─────────────┘ └──────────┘└─┘
doc └────────┘ └─────────────┘ └──────────┘
txt └────────┘ └─────────────┘ └──────────┘
par └────────┘ └─────────────┘ └──────────┘
pid ┴ ┴└────────────┘ ┴└────┘
st ─────────────────────────────┘└───────────────┘└─
1144 cases x, simpa using hxy, simp at hxy, simp [y_ih hxy.2, h hxy.1] }
id ┴ └─┘ └──┘ └─┘ ┴ └─┘
src └────┘ └──────────┘ └─────────┘ └────┘ ┴ └──┘ ┴ └──┘
typ └────┘┴ └──────────┘└─┘ └─────────┘ └────┘└──┘┴└─┘└──┘┴┴└─┘└──┘
doc └────┘ └──────────┘ └─────────┘ └────┘ ┴ └──┘ ┴ └──┘
txt └────┘ └──────────┘ └─────────┘ └────┘ ┴ └──┘ ┴ └──┘
par └────┘ └──────────┘ └─────────┘ └────┘ ┴ └──┘ ┴ └──┘
pid ┴ ┴└────┘ ┴└────┘ ┴┴ ┴ └──┘ ┴ └─┘┴
st ──────────┘└───────────────┘└───────────┘└───────────────────────────┘└─
1145 end
st ──┘
1146
1147 /- map₂ -/
1148
1149 theorem nil_map₂ (f : α → β → γ) (l : list β) : map₂ f [] l = [] :=
id ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ └┘ ┴ ┴ └┘
src └──┘ └──┘ └┘ ┴ └┘
typ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ └┘ ┴ ┴ └┘
1150 by cases l; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
1151
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1152 theorem map₂_nil (f : α → β → γ) (l : list α) : map₂ f l [] = [] :=
id ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ └┘ ┴ └┘
src └──┘ └──┘ └┘ ┴ └┘
typ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ └┘ ┴ └┘
1153 by cases l; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
1154
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
1155 /- take, drop -/
src ────────────────┘
typ ────────────────┘
doc ────────────────┘
txt ────────────────┘
par ────────────────┘
pid ────────────────┘
st ────────────────┘
1156 @[simp] theorem take_zero (l : list α) : take 0 l = [] := rfl
id └──┘ ┴ └──┘ ┴ ┴ └┘ └─┘
src └──┘ └──┘ ┴ └┘ └─┘
typ └──┘ ┴ └──┘ ┴ ┴ └┘ └─┘
doc └──┘
1157
1158 @[simp] theorem take_nil : ∀ n, take n [] = ([] : list α)
id ┴ └──┘ ┴ └┘ ┴ └┘ └──┘ ┴
src └──┘ └┘ ┴ └┘ └──┘
typ ┴ └──┘ ┴ └┘ ┴ └┘ └──┘ ┴
doc └──┘
1159 | 0 := rfl
id └─┘
src └─┘
typ └─┘
1160 | (n+1) := rfl
id ┴ └─┘
src ┴ └─┘
typ ┴ └─┘
1161
1162 theorem take_cons (n) (a : α) (l : list α) : take (succ n) (a::l) = a :: take n l := rfl
id ┴ └──┘ ┴ └──┘ └──┘ ┴ ┴└┘┴ ┴ ┴ └┘ └──┘ ┴ ┴ └─┘
src └──┘ └──┘ └──┘ └┘ ┴ └┘ └──┘ └─┘
typ ┴ └──┘ ┴ └──┘ └──┘ ┴ ┴└┘┴ ┴ ┴ └┘ └──┘ ┴ ┴ └─┘
1163
1164 @[simp] theorem take_all : ∀ (l : list α), take (length l) l = l
id ┴ └──┘ ┴ └──┘ └────┘ ┴ ┴ ┴ ┴
src └──┘ └──┘ └────┘ ┴
typ ┴ └──┘ ┴ └──┘ └────┘ ┴ ┴ ┴ ┴
doc └──┘
1165 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1166 | (a::l) := begin change a :: (take (length l) l) = a :: l, rw take_all end
id └┘ └──┘ └────┘ ┴ ┴ ┴ └──────┘
src └┘ └─────┘ ┴ ┴ └──┘┴ └────┘┴ └┘ └┘┴┴ ┴ ┴ └─┘ ┴
typ └┘ └─────┘ ┴ ┴ └──┘┴ └────┘┴ └┘ └┘┴┴┴┴ ┴┴ └─┘└──────┘┴
doc └─────┘ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └─┘ ┴
txt └─────┘ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └─┘ ┴
par └─────┘ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └─┘ ┴
pid ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ ┴ ┴
st └────────────────────────────────────────────┘└────────────┘└─┘
1167
1168 theorem take_all_of_le : ∀ {n} {l : list α}, length l ≤ n → take n l = l
id ┴┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ └────┘ ┴ └──┘ ┴
typ ┴┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
1169 | 0 [] h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1170 | 0 (a::l) h := absurd h (not_le_of_gt (zero_lt_succ _))
id └┘ ┴ └────┘ └──────────┘ └──────────┘
src └┘ └────┘ └──────────┘ └──────────┘
typ └┘ ┴ └────┘ └──────────┘ └──────────┘
1171 | (n+1) [] h := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
1172 | (n+1) (a::l) h :=
id ┴ └┘
src ┴ └┘
typ ┴ └┘
1173 begin
st └─────
1174 change a :: take n l = a :: l,
id └──┘ ┴ ┴ ┴ ┴
src └─────┘ ┴ ┴└──┘┴ ┴ ┴┴┴ ┴ ┴
typ └─────┘ ┴ ┴└──┘┴┴┴ ┴┴┴┴┴ ┴┴
doc └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
txt └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
par └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
st ────────────────────────────────┘└─
1175 rw [take_all_of_le (le_of_succ_le_succ h)]
id └────────────┘ └────────────────┘ ┴
src └──┘ ┴ └────────────────┘┴ └──
typ └──┘└────────────┘┴ └────────────────┘┴┴└──
doc └──┘ ┴ ┴ └──
txt └──┘ ┴ ┴ └──
par └──┘ ┴ ┴ └──
pid └┘ ┴ ┴ └┘└
st ────────────────────────────────────────────┘┴└
1176 end
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
1177
1178 @[simp] theorem take_left : ∀ l₁ l₂ : list α, take (length l₁) (l₁ ++ l₂) = l₁
id └┘ └──┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
src └──┘ └──┘ └────┘ └┘ ┴
typ └┘ └──┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
doc └──┘
1179 | [] l₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1180 | (a::l₁) l₂ := congr_arg (cons a) (take_left l₁ l₂)
id ┴└┘└┘ └┘ └───────┘ └──┘ └───────┘
src └┘ └───────┘ └──┘
typ ┴└┘└┘ └┘ └───────┘ └──┘ └───────┘
1181
1182 theorem take_left' {l₁ l₂ : list α} {n} (h : length l₁ = n) :
id └──┘ ┴ └────┘ └┘ ┴ ┴
src └──┘ └────┘ ┴
typ └──┘ ┴ └────┘ └┘ ┴ ┴
1183 take n (l₁ ++ l₂) = l₁ :=
id └──┘ ┴ └┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ ┴ └┘
1184 by rw ← h; apply take_left
id ┴ └───────┘
src └───┘ └────┘└───────┘└
typ └───┘┴ └────┘└───────┘└
doc └───┘ └────┘ └
txt └───┘ └────┘ └
par └───┘ └────┘ └
pid └─┘ ┴ └
st └────────────────────────
1185
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1186 theorem take_take : ∀ (n m) (l : list α), take n (take m l) = take (min n m) l
id ┴┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──┘ └─┘ ┴ ┴ ┴
src └──┘ └──┘ └──┘ ┴ └──┘ └─┘
typ ┴┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──┘ └─┘ ┴ ┴ ┴
1187 | n 0 l := by rw [min_zero, take_zero, take_nil]
id └──────┘ └───────┘ └──────┘
src └──┘└──────┘└┘└───────┘└┘└──────┘└┘
typ └──┘└──────┘└┘└───────┘└┘└──────┘└┘
doc └──┘ └┘ └┘ └┘
txt └──┘ └┘ └┘ └┘
par └──┘ └┘ └┘ └┘
pid └┘ └┘ └┘ ┴┴
st └───────────┘└─────────┘└────────┘┴┴
1188 | 0 m l := by rw [zero_min, take_zero, take_zero]
id └──────┘ └───────┘ └───────┘
src └──┘└──────┘└┘└───────┘└┘└───────┘└┘
typ └──┘└──────┘└┘└───────┘└┘└───────┘└┘
doc └──┘ └┘ └┘ └┘
txt └──┘ └┘ └┘ └┘
par └──┘ └┘ └┘ └┘
pid └┘ └┘ └┘ ┴┴
st └───────────┘└─────────┘└─────────┘┴┴
1189 | (succ n) (succ m) nil := by simp only [take_nil]
id └──┘ └─┘ └──────┘
src └──┘ └─┘ └─────────┘└──────┘└┘
typ └──┘ └─┘ └─────────┘└──────┘└┘
doc └─────────┘ └┘
txt └─────────┘ └┘
par └─────────┘ └┘
pid ┴└──┘└┘ ┴┴
st └────────────────────┘
1190 | (succ n) (succ m) (a::l) := by simp only [take, min_succ_succ, take_take n m l]; split; refl
id └──┘ └┘ └──┘ └───────────┘ └───────┘ ┴ ┴ ┴
src └──┘ └┘ └─────────┘└──┘└┘└───────────┘└┘ ┴ ┴ ┴ ┴ └───┘ └────
typ └──┘ └┘ └─────────┘└──┘└┘└───────────┘└┘└───────┘┴┴┴┴┴┴┴ └───┘ └────
doc └─────────┘ └┘ └┘ ┴ ┴ ┴ ┴ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ ┴ ┴ ┴ └───┘ └────
par └─────────┘ └┘ └┘ ┴ ┴ ┴ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ ┴ ┴ └
st └──────────────────────────────────────────────────────────────
1191
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1192 @[simp] theorem drop_nil : ∀ n, drop n [] = ([] : list α)
id ┴ └──┘ ┴ └┘ ┴ └┘ └──┘ ┴
src └──┘ └┘ ┴ └┘ └──┘
typ ┴ └──┘ ┴ └┘ ┴ └┘ └──┘ ┴
doc └──┘
1193 | 0 := rfl
id └─┘
src └─┘
typ └─┘
1194 | (n+1) := rfl
id ┴ └─┘
src ┴ └─┘
typ ┴ └─┘
1195
1196 @[simp] theorem drop_one : ∀ l : list α, drop 1 l = tail l
id ┴ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘ ┴ └──┘
typ ┴ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴
doc └──┘
1197 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1198 | (a :: l) := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1199
1200 theorem drop_add : ∀ m n (l : list α), drop (m + n) l = drop m (drop n l)
id ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴
src └──┘ └──┘ ┴ ┴ └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴
1201 | m 0 l := rfl
id └─┘
src └─┘
typ └─┘
1202 | m (n+1) [] := (drop_nil _).symm
id ┴ └┘ └──────┘ └──┘
src ┴ └┘ └──────┘ └──┘
typ ┴ └┘ └──────┘ └──┘
1203 | m (n+1) (a::l) := drop_add m n _
id ┴ ┴┴ └┘ └──────┘
src ┴ └┘
typ ┴ ┴┴ └┘ └──────┘
1204
1205 @[simp] theorem drop_left : ∀ l₁ l₂ : list α, drop (length l₁) (l₁ ++ l₂) = l₂
id └┘ └──┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
src └──┘ └──┘ └────┘ └┘ ┴
typ └┘ └──┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
doc └──┘
1206 | [] l₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1207 | (a::l₁) l₂ := drop_left l₁ l₂
id └┘└┘ └┘ └───────┘
src └┘
typ └┘└┘ └┘ └───────┘
1208
1209 theorem drop_left' {l₁ l₂ : list α} {n} (h : length l₁ = n) :
id └──┘ ┴ └────┘ └┘ ┴ ┴
src └──┘ └────┘ ┴
typ └──┘ ┴ └────┘ └┘ ┴ ┴
1210 drop n (l₁ ++ l₂) = l₂ :=
id └──┘ ┴ └┘ └┘ └┘ ┴ └┘
src └──┘ └┘ ┴
typ └──┘ ┴ └┘ └┘ └┘ ┴ └┘
1211 by rw ← h; apply drop_left
id ┴ └───────┘
src └───┘ └────┘└───────┘└
typ └───┘┴ └────┘└───────┘└
doc └───┘ └────┘ └
txt └───┘ └────┘ └
par └───┘ └────┘ └
pid └─┘ ┴ └
st └────────────────────────
1212
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1213 theorem drop_eq_nth_le_cons : ∀ {n} {l : list α} h,
id ┴┴ └──┘ ┴ ┴
src └──┘
typ ┴┴ └──┘ ┴ ┴
1214 drop n l = nth_le l n h :: drop (n+1) l
id └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └┘ └──┘ ┴┴ ┴
src └──┘ ┴ └────┘ └┘ └──┘ ┴
typ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └┘ └──┘ ┴┴ ┴
1215 | 0 (a::l) h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1216 | (n+1) (a::l) h := @drop_eq_nth_le_cons n _ _
id ┴┴ └┘ └─────────────────┘
src ┴ └┘
typ ┴┴ └┘ └─────────────────┘
1217
1218 @[simp] lemma drop_all (l : list α) : l.drop l.length = [] :=
id └──┘ ┴ ┴└───┘ ┴└─────┘ ┴ └┘
src └──┘ └───┘ └─────┘ ┴ └┘
typ └──┘ ┴ ┴└───┘ ┴└─────┘ ┴ └┘
doc └──┘
1219 calc l.drop l.length = (l ++ []).drop l.length : by simp
id ┴└───┘ ┴└─────┘ ┴ └┘ └┘ └──┘ ┴└─────┘
src └───┘ └─────┘ └┘ └┘ └──┘ └─────┘ └────
typ ┴└───┘ ┴└─────┘ ┴ └┘ └┘ └──┘ ┴└─────┘ └────
doc └────
txt └────
par └────
pid └
st └─────
1220 ... = [] : drop_left _ _
id └┘ └───────┘
src ────────────────┘ └┘ └───────┘
typ ────────────────┘ └┘ └───────┘
doc ────────────────┘
txt ────────────────┘
par ────────────────┘
pid ────────────────┘
st ────────────────┘
1221
1222 lemma drop_append_of_le_length : ∀ {l₁ l₂ : list α} {n : ℕ}, n ≤ l₁.length →
id ┴ └──┘ ┴ ┴ ┴ ┴ └┘└─────┘
src └──┘ ┴ ┴ └─────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └┘└─────┘
1223 (l₁ ++ l₂).drop n = l₁.drop n ++ l₂
id └┘ └┘ └┘ └──┘ ┴ ┴ └┘└───┘ ┴ └┘ └┘
src └┘ └──┘ ┴ └───┘ └┘
typ └┘ └┘ └┘ └──┘ ┴ ┴ └┘└───┘ ┴ └┘ └┘
1224 | l₁ l₂ 0 hn := by simp
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
1225 | [] l₂ (n+1) hn := absurd hn dec_trivial
id └┘ ┴ └┘ └────┘ └─────────┘
src └┘ ┴ └────┘ └─────────┘
typ └┘ ┴ └┘ └────┘ └─────────┘
doc └─────────┘
1226 | (a::l₁) l₂ (n+1) hn :=
id └┘ ┴
src └┘ ┴
typ └┘ ┴
1227 by rw [drop, cons_append, drop, drop_append_of_le_length (le_of_succ_le_succ hn)]
id └──┘ └─────────┘ └──┘ └──────────────────────┘ └────────────────┘ └┘
src └──┘└──┘└┘└─────────┘└┘└──┘└┘ ┴ └────────────────┘┴ └──
typ └──┘└──┘└┘└─────────┘└┘└──┘└┘└──────────────────────┘┴ └────────────────┘┴└┘└──
doc └──┘ └┘ └┘ └┘ ┴ ┴ └──
txt └──┘ └┘ └┘ └┘ ┴ ┴ └──
par └──┘ └┘ └┘ └┘ ┴ ┴ └──
pid └┘ └┘ └┘ └┘ ┴ ┴ └┘└
st └───────┘└───────────┘└────┘└────────────────────────────────────────────────┘┴└
1228
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1229 lemma take_append_of_le_length : ∀ {l₁ l₂ : list α} {n : ℕ},
id ┴ └──┘ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴
1230 n ≤ l₁.length → (l₁ ++ l₂).take n = l₁.take n
id ┴ ┴ └┘└─────┘ └┘ └┘ └┘ └──┘ ┴ ┴ └┘└───┘ ┴
src ┴ └─────┘ └┘ └──┘ ┴ └───┘
typ ┴ ┴ └┘└─────┘ └┘ └┘ └┘ └──┘ ┴ ┴ └┘└───┘ ┴
1231 | l₁ l₂ 0 hn := by simp
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
1232 | [] l₂ (n+1) hn := absurd hn dec_trivial
id └┘ ┴ └┘ └────┘ └─────────┘
src └┘ ┴ └────┘ └─────────┘
typ └┘ ┴ └┘ └────┘ └─────────┘
doc └─────────┘
1233 | (a::l₁) l₂ (n+1) hn :=
id └┘ ┴
src └┘ ┴
typ └┘ ┴
1234 by rw [list.take, list.cons_append, list.take, take_append_of_le_length (le_of_succ_le_succ hn)]
id └───────┘ └──────────────┘ └───────┘ └──────────────────────┘ └────────────────┘ └┘
src └──┘└───────┘└┘└──────────────┘└┘└───────┘└┘ ┴ └────────────────┘┴ └──
typ └──┘└───────┘└┘└──────────────┘└┘└───────┘└┘└──────────────────────┘┴ └────────────────┘┴└┘└──
doc └──┘ └┘ └┘ └┘ ┴ ┴ └──
txt └──┘ └┘ └┘ └┘ ┴ ┴ └──
par └──┘ └┘ └┘ └┘ ┴ ┴ └──
pid └┘ └┘ └┘ └┘ ┴ ┴ └┘└
st └────────────┘└────────────────┘└─────────┘└────────────────────────────────────────────────┘┴└
1235
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1236 @[simp] theorem drop_drop (n : ℕ) : ∀ (m) (l : list α), drop n (drop m l) = drop (n + m) l
id ┴ ┴┴ └──┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src ┴ └──┘ └──┘ └──┘ ┴ └──┘ ┴
typ ┴ ┴┴ └──┘ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘
1237 | m [] := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
1238 | 0 l := by simp
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
1239 | (m+1) (a::l) :=
id ┴┴ ┴└┘┴
src ┴ └┘
typ ┴┴ ┴└┘┴
1240 calc drop n (drop (m + 1) (a :: l)) = drop n (drop m l) : rfl
id └──┘ ┴ └──┘ ┴ └┘ └──┘ ┴ └──┘ └─┘
src └──┘ └──┘ ┴ └┘ └──┘ └──┘ └─┘
typ └──┘ ┴ └──┘ ┴ └┘ └──┘ ┴ └──┘ └─┘
1241 ... = drop (n + m) l : drop_drop m l
id └──┘ ┴ ┴ └───────┘
src └──┘ ┴
typ └──┘ ┴ ┴ └───────┘
1242 ... = drop (n + (m + 1)) (a :: l) : rfl
id └──┘ ┴ ┴ ┴ └┘ └─┘
src └──┘ ┴ ┴ └┘ └─┘
typ └──┘ ┴ ┴ ┴ └┘ └─┘
1243
1244 theorem drop_take : ∀ (m : ℕ) (n : ℕ) (l : list α),
id ┴ ┴ ┴ └──┘ ┴
src ┴ ┴ └──┘
typ ┴ ┴ ┴ └──┘ ┴
1245 drop m (take (m + n) l) = take n (drop m l)
id └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴
src └──┘ └──┘ ┴ ┴ └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴
1246 | 0 n _ := by simp
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
1247 | (m+1) n nil := by simp
id ┴ └─┘
src ┴ └─┘ └───┘
typ ┴ └─┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
1248 | (m+1) n (_::l) :=
id ┴┴ ┴ └┘
src ┴ └┘
typ ┴┴ ┴ └┘
1249 have h: m + 1 + n = (m+n) + 1, by simp,
id ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴ ┴ ┴ └──┘
typ ┴ ┴ ┴ ┴ ┴ └──┘
doc └──┘
txt └──┘
par └──┘
st └───┘
1250 by simpa [take_cons, h] using drop_take m n l
id └───────┘ ┴ └───────┘ ┴ ┴ ┴
src └─────┘└───────┘└┘ └──────┘ ┴ ┴ ┴ └
typ └─────┘└───────┘└┘┴└──────┘└───────┘┴┴┴┴┴┴└
doc └─────┘ └┘ └──────┘ ┴ ┴ ┴ └
txt └─────┘ └┘ └──────┘ ┴ ┴ ┴ └
par └─────┘ └┘ └──────┘ ┴ ┴ ┴ └
pid ┴┴ └┘ ┴┴└────┘ ┴ ┴ ┴ └
st └───────────────────────────────────────────
1251
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1252 theorem modify_nth_tail_eq_take_drop (f : list α → list α) (H : f [] = []) :
id └──┘ ┴ └──┘ ┴ ┴ └┘ ┴ └┘
src └──┘ └──┘ └┘ ┴ └┘
typ └──┘ ┴ └──┘ ┴ ┴ └┘ ┴ └┘
1253 ∀ n l, modify_nth_tail f n l = take n l ++ f (drop n l)
id ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ ┴ └──┘ ┴ ┴
src └─────────────┘ ┴ └──┘ └┘ └──┘
typ ┴ ┴ └─────────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ ┴ └──┘ ┴ ┴
doc └─────────────┘
1254 | 0 l := rfl
id └─┘
src └─┘
typ └─┘
1255 | (n+1) [] := H.symm
id ┴ └┘ ┴└───┘
src ┴ └┘ └───┘
typ ┴ └┘ ┴└───┘
1256 | (n+1) (b::l) := congr_arg (cons b) (modify_nth_tail_eq_take_drop n l)
id ┴┴ ┴└┘┴ └───────┘ └──┘ └──────────────────────────┘
src ┴ └┘ └───────┘ └──┘
typ ┴┴ ┴└┘┴ └───────┘ └──┘ └──────────────────────────┘
1257
1258 theorem modify_nth_eq_take_drop (f : α → α) :
id ┴ ┴
typ ┴ ┴
1259 ∀ n l, modify_nth f n l = take n l ++ modify_head f (drop n l) :=
id ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ └─────────┘ ┴ └──┘ ┴ ┴
src └────────┘ ┴ └──┘ └┘ └─────────┘ └──┘
typ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ └─────────┘ ┴ └──┘ ┴ ┴
doc └────────┘ └─────────┘
1260 modify_nth_tail_eq_take_drop _ rfl
id └──────────────────────────┘ └─┘
src └──────────────────────────┘ └─┘
typ └──────────────────────────┘ └─┘
1261
1262 theorem modify_nth_eq_take_cons_drop (f : α → α) {n l} (h) :
id ┴ ┴
typ ┴ ┴
1263 modify_nth f n l = take n l ++ f (nth_le l n h) :: drop (n+1) l :=
id └────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ ┴ └┘ └──┘ ┴┴ ┴
src └────────┘ ┴ └──┘ └┘ └────┘ └┘ └──┘ ┴
typ └────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ ┴ └┘ └──┘ ┴┴ ┴
doc └────────┘
1264 by rw [modify_nth_eq_take_drop, drop_eq_nth_le_cons h]; refl
id └─────────────────────┘ └─────────────────┘ ┴
src └──┘└─────────────────────┘└┘└─────────────────┘┴ ┴ └────
typ └──┘└─────────────────────┘└┘└─────────────────┘┴┴┴ └────
doc └──┘ └┘ ┴ ┴ └────
txt └──┘ └┘ ┴ ┴ └────
par └──┘ └┘ ┴ ┴ └────
pid └┘ └┘ ┴ ┴ └
st └──────────────────────────┘└─────────────────────┘┴└──────
1265
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1266 theorem update_nth_eq_take_cons_drop (a : α) {n l} (h : n < length l) :
id ┴ ┴ ┴ └────┘ ┴
src ┴ └────┘
typ ┴ ┴ ┴ └────┘ ┴
1267 update_nth l n a = take n l ++ a :: drop (n+1) l :=
id └────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ ┴ └┘ └──┘ ┴┴ ┴
src └────────┘ ┴ └──┘ └┘ └┘ └──┘ ┴
typ └────────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └┘ ┴ └┘ └──┘ ┴┴ ┴
1268 by rw [update_nth_eq_modify_nth, modify_nth_eq_take_cons_drop _ h]
id └──────────────────────┘ └──────────────────────────┘ ┴
src └──┘└──────────────────────┘└┘└──────────────────────────┘└─┘ └─
typ └──┘└──────────────────────┘└┘└──────────────────────────┘└─┘┴└─
doc └──┘ └┘ └─┘ └─
txt └──┘ └┘ └─┘ └─
par └──┘ └┘ └─┘ └─
pid └┘ └┘ └─┘ ┴└
st └───────────────────────────┘└────────────────────────────────┘┴└
1269
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1270 @[simp] lemma update_nth_eq_nil (l : list α) (n : ℕ) (a : α) : l.update_nth n a = [] ↔ l = [] :=
id └──┘ ┴ ┴ ┴ ┴└─────────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ ┴ └─────────┘ ┴ └┘ ┴ ┴ └┘
typ └──┘ ┴ ┴ ┴ ┴└─────────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
1271 by cases l; cases n; simp only [update_nth]
id ┴ ┴ └────────┘
src └────┘ └────┘ └─────────┘└────────┘└─
typ └────┘┴ └────┘┴ └─────────┘└────────┘└─
doc └────┘ └────┘ └─────────┘ └─
txt └────┘ └────┘ └─────────┘ └─
par └────┘ └────┘ └─────────┘ └─
pid ┴ ┴ ┴└──┘└┘ ┴└
st └─────────────────────────────────────────
1272
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1273 section take'
1274 variable [inhabited α]
id └───────┘
src └───────┘
typ └───────┘
1275
1276 @[simp] theorem take'_length : ∀ n l, length (@take' α _ n l) = n
id ┴ ┴ └────┘ └───┘ ┴ ┴ ┴ ┴ ┴
src └────┘ └───┘ ┴
typ ┴ ┴ └────┘ └───┘ ┴ ┴ ┴ ┴ ┴
doc └──┘
1277 | 0 l := rfl
id └─┘
src └─┘
typ └─┘
1278 | (n+1) l := congr_arg succ (take'_length _ _)
id ┴ └───────┘ └──┘ └──────────┘
src ┴ └───────┘ └──┘
typ ┴ └───────┘ └──┘ └──────────┘
1279
1280 @[simp] theorem take'_nil : ∀ n, take' n (@nil α) = repeat (default _) n
id ┴ └───┘ ┴ └─┘ ┴ ┴ └────┘ └─────┘ ┴
src └───┘ └─┘ ┴ └────┘ └─────┘
typ ┴ └───┘ ┴ └─┘ ┴ ┴ └────┘ └─────┘ ┴
doc └──┘
1281 | 0 := rfl
id └─┘
src └─┘
typ └─┘
1282 | (n+1) := congr_arg (cons _) (take'_nil _)
id ┴ └───────┘ └──┘ └───────┘
src ┴ └───────┘ └──┘
typ ┴ └───────┘ └──┘ └───────┘
1283
1284 theorem take'_eq_take : ∀ {n} {l : list α},
id ┴┴ └──┘ ┴
src └──┘
typ ┴┴ └──┘ ┴
1285 n ≤ length l → take' n l = take n l
id ┴ ┴ └────┘ ┴ └───┘ ┴ ┴ ┴ └──┘ ┴ ┴
src ┴ └────┘ └───┘ ┴ └──┘
typ ┴ ┴ └────┘ ┴ └───┘ ┴ ┴ ┴ └──┘ ┴ ┴
1286 | 0 l h := rfl
id └─┘
src └─┘
typ └─┘
1287 | (n+1) (a::l) h := congr_arg (cons _) $
id ┴ └┘ ┴ └───────┘ └──┘
src ┴ └┘ └───────┘ └──┘
typ ┴ └┘ ┴ └───────┘ └──┘
1288 take'_eq_take $ le_of_succ_le_succ h
id └───────────┘ └────────────────┘
src └────────────────┘
typ └───────────┘ └────────────────┘
1289
1290 @[simp] theorem take'_left (l₁ l₂ : list α) : take' (length l₁) (l₁ ++ l₂) = l₁ :=
id └──┘ ┴ └───┘ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
src └──┘ └───┘ └────┘ └┘ ┴
typ └──┘ ┴ └───┘ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
doc └──┘
1291 (take'_eq_take (by simp only [length_append, nat.le_add_right])).trans (take_left _ _)
id └───────────┘ └───────────┘ └──────────────┘ └───┘ └───────┘
src └───────────┘ └─────────┘└───────────┘└┘└──────────────┘┴ └───┘ └───────┘
typ └───────────┘ └─────────┘└───────────┘└┘└──────────────┘┴ └───┘ └───────┘
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st └──────────────────────────────────────────┘
1292
1293 theorem take'_left' {l₁ l₂ : list α} {n} (h : length l₁ = n) :
id └──┘ ┴ └────┘ └┘ ┴ ┴
src └──┘ └────┘ ┴
typ └──┘ ┴ └────┘ └┘ ┴ ┴
1294 take' n (l₁ ++ l₂) = l₁ :=
id └───┘ ┴ └┘ └┘ └┘ ┴ └┘
src └───┘ └┘ ┴
typ └───┘ ┴ └┘ └┘ └┘ ┴ └┘
1295 by rw ← h; apply take'_left
id ┴ └────────┘
src └───┘ └────┘└────────┘└
typ └───┘┴ └────┘└────────┘└
doc └───┘ └────┘ └
txt └───┘ └────┘ └
par └───┘ └────┘ └
pid └─┘ ┴ └
st └─────────────────────────
1296
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1297 end take'
1298
1299 /- foldl, foldr -/
1300
1301 lemma foldl_ext (f g : α → β → α) (a : α)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
1302 {l : list β} (H : ∀ a : α, ∀ b ∈ l, f a b = g a b) :
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1303 foldl f a l = foldl g a l :=
id └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └───┘ ┴ └───┘
typ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
1304 begin
st └─────
1305 induction l with hd tl ih generalizing a, {refl},
id ┴
src └────────┘ └───────────────────────────┘ └──┘
typ └────────┘┴└───────────────────────────┘ └──┘
doc └────────┘ └───────────────────────────┘ └──┘
txt └────────┘ └───────────────────────────┘ └──┘
par └────────┘ └───────────────────────────┘ └──┘
pid ┴ ┴└───────────┘└─────────────┘
st ─────────────────────────────────────────┘└─────┘└┘└
1306 unfold foldl,
src └──────────┘
typ └──────────┘
doc └──────────┘
txt └──────────┘
par └──────────┘
pid └────┘
st ─────────────┘└─
1307 rw [ih (λ a b bin, H a b $ mem_cons_of_mem _ bin), H a hd (mem_cons_self _ _)]
id └┘ ┴ └─────────────┘ ┴ ┴ └┘ └───────────┘
src └──┘ ┴ └────────┘ ┴ ┴ ┴ ┴└─────────────┘└─┘ └─┘ ┴ ┴ ┴ └───────────┘└─────┘
typ └──┘└┘┴ └────────┘┴┴ ┴ ┴ ┴└─────────────┘└─┘ └─┘┴┴┴┴└┘┴ └───────────┘└─────┘
doc └──┘ ┴ └────────┘ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ ┴ └─────┘
txt └──┘ ┴ └────────┘ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ ┴ └─────┘
par └──┘ ┴ └────────┘ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ ┴ └─────┘
pid └┘ ┴ └────────┘ ┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴ ┴ └────┘┴
st ──────────────────────────────────────────────────┘└──────────────────────────┘┴┴
1308 end
st └─┘
1309
1310 lemma foldr_ext (f g : α → β → β) (b : β)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
1311 {l : list α} (H : ∀ a ∈ l, ∀ b : β, f a b = g a b) :
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1312 foldr f b l = foldr g b l :=
id └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └───┘ ┴ └───┘
typ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
1313 begin
st └─────
1314 induction l with hd tl ih, {refl},
id ┴
src └────────┘ └────────────┘ └──┘
typ └────────┘┴└────────────┘ └──┘
doc └────────┘ └────────────┘ └──┘
txt └────────┘ └────────────┘ └──┘
par └────────┘ └────────────┘ └──┘
pid ┴ ┴└───────────┘
st ──────────────────────────┘└─────┘└┘└
1315 simp only [mem_cons_iff, or_imp_distrib, forall_and_distrib, forall_eq] at H,
id └──────────┘ └────────────┘ └────────────────┘ └───────┘
src └─────────┘└──────────┘└┘└────────────┘└┘└────────────────┘└┘└───────┘└────┘
typ └─────────┘└──────────┘└┘└────────────┘└┘└────────────────┘└┘└───────┘└────┘
doc └─────────┘ └┘ └┘ └┘ └────┘
txt └─────────┘ └┘ └┘ └┘ └────┘
par └─────────┘ └┘ └┘ └┘ └────┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴┴└──┘
st ─────────────────────────────────────────────────────────────────────────────┘└─
1316 simp only [foldr, ih H.2, H.1]
id └───┘ └┘ ┴ ┴
src └─────────┘└───┘└┘ ┴ └──┘ └──┘
typ └─────────┘└───┘└┘└┘┴┴└──┘┴└──┘
doc └─────────┘ └┘ ┴ └──┘ └──┘
txt └─────────┘ └┘ ┴ └──┘ └──┘
par └─────────┘ └┘ ┴ └──┘ └──┘
pid ┴└──┘└┘ └┘ ┴ └──┘ └─┘┴
st ────────────────────────────────┘
1317 end
st └─┘
1318
1319 @[simp] theorem foldl_nil (f : α → β → α) (a : α) : foldl f a [] = a := rfl
id ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴ ┴ └─┘
src └───┘ └┘ ┴ └─┘
typ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴ ┴ └─┘
doc └──┘
1320
1321 @[simp] theorem foldl_cons (f : α → β → α) (a : α) (b : β) (l : list β) :
id ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1322 foldl f a (b::l) = foldl f (f a b) l := rfl
id └───┘ ┴ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ └─┘
src └───┘ └┘ ┴ └───┘ └─┘
typ └───┘ ┴ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ └─┘
1323
1324 @[simp] theorem foldr_nil (f : α → β → β) (b : β) : foldr f b [] = b := rfl
id ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴ ┴ └─┘
src └───┘ └┘ ┴ └─┘
typ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴ ┴ └─┘
doc └──┘
1325
1326 @[simp] theorem foldr_cons (f : α → β → β) (b : β) (a : α) (l : list α) :
id ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1327 foldr f b (a::l) = f a (foldr f b l) := rfl
id └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘
src └───┘ └┘ ┴ └───┘ └─┘
typ └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘
1328
1329 @[simp] theorem foldl_append (f : α → β → α) :
id ┴ ┴ ┴
typ ┴ ┴ ┴
doc └──┘
1330 ∀ (a : α) (l₁ l₂ : list β), foldl f a (l₁++l₂) = foldl f (foldl f a l₁) l₂
id ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └┘└┘└┘ ┴ └───┘ ┴ └───┘ ┴ ┴ └┘ └┘
src └──┘ └───┘ └┘ ┴ └───┘ └───┘
typ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └┘└┘└┘ ┴ └───┘ ┴ └───┘ ┴ ┴ └┘ └┘
1331 | a [] l₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1332 | a (b::l₁) l₂ := by simp only [cons_append, foldl_cons, foldl_append (f a b) l₁ l₂]
id └┘ └─────────┘ └────────┘ └──────────┘ ┴ ┴ ┴ └┘ └┘
src └┘ └─────────┘└─────────┘└┘└────────┘└┘ ┴ ┴ ┴ └┘ ┴ └─
typ └┘ └─────────┘└─────────┘└┘└────────┘└┘└──────────┘┴ ┴┴┴┴┴└┘└┘┴└┘└─
doc └─────────┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ └─
txt └─────────┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ └─
par └─────────┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴└
st └────────────────────────────────────────────────────────────────
1333
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1334 @[simp] theorem foldr_append (f : α → β → β) :
id ┴ ┴ ┴
typ ┴ ┴ ┴
doc └──┘
1335 ∀ (b : β) (l₁ l₂ : list α), foldr f b (l₁++l₂) = foldr f (foldr f b l₂) l₁
id ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └┘└┘└┘ ┴ └───┘ ┴ └───┘ ┴ ┴ └┘ └┘
src └──┘ └───┘ └┘ ┴ └───┘ └───┘
typ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └┘└┘└┘ ┴ └───┘ ┴ └───┘ ┴ ┴ └┘ └┘
1336 | b [] l₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1337 | b (a::l₁) l₂ := by simp only [cons_append, foldr_cons, foldr_append b l₁ l₂]
id └┘ └─────────┘ └────────┘ └──────────┘ ┴ └┘ └┘
src └┘ └─────────┘└─────────┘└┘└────────┘└┘ ┴ ┴ ┴ └─
typ └┘ └─────────┘└─────────┘└┘└────────┘└┘└──────────┘┴┴┴└┘┴└┘└─
doc └─────────┘ └┘ └┘ ┴ ┴ ┴ └─
txt └─────────┘ └┘ └┘ ┴ ┴ ┴ └─
par └─────────┘ └┘ └┘ ┴ ┴ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ ┴ ┴└
st └──────────────────────────────────────────────────────────
1338
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1339 @[simp] theorem foldl_join (f : α → β → α) :
id ┴ ┴ ┴
typ ┴ ┴ ┴
doc └──┘
1340 ∀ (a : α) (L : list (list β)), foldl f a (join L) = foldl (foldl f) a L
id ┴ ┴ └──┘ └──┘ ┴ └───┘ ┴ ┴ └──┘ ┴ ┴ └───┘ └───┘ ┴ ┴ ┴
src └──┘ └──┘ └───┘ └──┘ ┴ └───┘ └───┘
typ ┴ ┴ └──┘ └──┘ ┴ └───┘ ┴ ┴ └──┘ ┴ ┴ └───┘ └───┘ ┴ ┴ ┴
1341 | a [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1342 | a (l::L) := by simp only [join, foldl_append, foldl_cons, foldl_join (foldl f a l) L]
id └┘ └──┘ └──────────┘ └────────┘ └────────┘ └───┘ ┴ ┴ ┴ ┴
src └┘ └─────────┘└──┘└┘└──────────┘└┘└────────┘└┘ ┴ └───┘┴ ┴ ┴ └┘ └─
typ └┘ └─────────┘└──┘└┘└──────────┘└┘└────────┘└┘└────────┘┴ └───┘┴┴┴┴┴┴└┘┴└─
doc └─────────┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ └─
txt └─────────┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ └─
par └─────────┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ ┴└
st └───────────────────────────────────────────────────────────────────────
1343
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1344 @[simp] theorem foldr_join (f : α → β → β) :
id ┴ ┴ ┴
typ ┴ ┴ ┴
doc └──┘
1345 ∀ (b : β) (L : list (list α)), foldr f b (join L) = foldr (λ l b, foldr f b l) b L
id ┴ ┴ └──┘ └──┘ ┴ └───┘ ┴ ┴ └──┘ ┴ ┴ └───┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ └───┘ └──┘ ┴ └───┘ └───┘
typ ┴ ┴ └──┘ └──┘ ┴ └───┘ ┴ ┴ └──┘ ┴ ┴ └───┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
1346 | a [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1347 | a (l::L) := by simp only [join, foldr_append, foldr_join a L, foldr_cons]
id └┘ └──┘ └──────────┘ └────────┘ ┴ ┴ └────────┘
src └┘ └─────────┘└──┘└┘└──────────┘└┘ ┴ ┴ └┘└────────┘└─
typ └┘ └─────────┘└──┘└┘└──────────┘└┘└────────┘┴┴┴┴└┘└────────┘└─
doc └─────────┘ └┘ └┘ ┴ ┴ └┘ └─
txt └─────────┘ └┘ └┘ ┴ ┴ └┘ └─
par └─────────┘ └┘ └┘ ┴ ┴ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └┘ ┴└
st └───────────────────────────────────────────────────────────
1348
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1349 theorem foldl_reverse (f : α → β → α) (a : α) (l : list β) : foldl f a (reverse l) = foldr (λx y, f y x) a l :=
id ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └─────┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └───┘ └─────┘ ┴ └───┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └─────┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1350 by induction l; [refl, simp only [*, reverse_cons, foldl_append, foldl_cons, foldl_nil, foldr]]
id ┴ ┴ └──────────┘ └──────────┘ └────────┘ └───────┘ └───┘
src └────────┘ ┴└──┘ └────────────┘└──────────┘└┘└──────────┘└┘└────────┘└┘└───────┘└┘└───┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└──────────┘└┘└──────────┘└┘└────────┘└┘└───────┘└┘└───┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ └┘ └┘ ┴
st └───────────────────────────────────────────────────────────────────────────────────────────┘
1351
1352 theorem foldr_reverse (f : α → β → β) (a : β) (l : list α) : foldr f a (reverse l) = foldl (λx y, f y x) a l :=
id ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └─────┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └───┘ └─────┘ ┴ └───┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ └─────┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1353 let t := foldl_reverse (λx y, f y x) a (reverse l) in
id ┴ └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
src └───────────┘ └─────┘
typ ┴ └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
1354 by rw reverse_reverse l at t; rwa t
id └─────────────┘ ┴ ┴
src └─┘└─────────────┘┴ └───┘ └──┘ └
typ └─┘└─────────────┘┴┴└───┘ └──┘┴└
doc └─┘ ┴ └───┘ └──┘ └
txt └─┘ ┴ └───┘ └──┘ └
par └─┘ ┴ └───┘ └──┘ └
pid ┴ ┴ └───┘ ┴ └
st └──────────────────────────────┘┴└
1355
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1356 @[simp] theorem foldr_eta : ∀ (l : list α), foldr cons [] l = l
id ┴ └──┘ ┴ └───┘ └──┘ └┘ ┴ ┴ ┴
src └──┘ └───┘ └──┘ └┘ ┴
typ ┴ └──┘ ┴ └───┘ └──┘ └┘ ┴ ┴ ┴
doc └──┘
1357 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1358 | (x::l) := by simp only [foldr_cons, foldr_eta l]; split; refl
id └┘ └────────┘ └───────┘ ┴
src └┘ └─────────┘└────────┘└┘ ┴ ┴ └───┘ └────
typ └┘ └─────────┘└────────┘└┘└───────┘┴┴┴ └───┘ └────
doc └─────────┘ └┘ ┴ ┴ └───┘ └────
txt └─────────┘ └┘ ┴ ┴ └───┘ └────
par └─────────┘ └┘ ┴ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ ┴ ┴ └
st └─────────────────────────────────────────────────
1359
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1360 @[simp] theorem reverse_foldl {l : list α} : reverse (foldl (λ t h, h :: t) [] l) = l :=
id └──┘ ┴ └─────┘ └───┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴
src └──┘ └─────┘ └───┘ └┘ └┘ ┴
typ └──┘ ┴ └─────┘ └───┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴
doc └──┘
1361 by rw ←foldr_reverse; simp
id └───────────┘
src └──┘└───────────┘ └────
typ └──┘└───────────┘ └────
doc └──┘ └────
txt └──┘ └────
par └──┘ └────
pid └┘ └
st └────────────────────────
1362
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
1363 /- scanl -/
src ────────────
typ ────────────
doc ────────────
txt ────────────
par ────────────
pid ────────────
st ────────────
1364
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1365 lemma length_scanl {β : Type*} {f : α → β → α} :
id ┴ ┴ ┴
typ ┴ ┴ ┴
1366 ∀ a l, length (scanl f a l) = l.length + 1
id ┴ ┴ └────┘ └───┘ ┴ ┴ ┴ ┴ ┴└─────┘ ┴
src └────┘ └───┘ ┴ └─────┘ ┴
typ ┴ ┴ └────┘ └───┘ ┴ ┴ ┴ ┴ ┴└─────┘ ┴
doc └───┘
1367 | a [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1368 | a (x :: l) := by erw [length_cons, length_cons, length_scanl]
id └┘ └─────────┘ └─────────┘ └──────────┘
src └┘ └───┘└─────────┘└┘└─────────┘└┘ └─
typ └┘ └───┘└─────────┘└┘└─────────┘└┘└──────────┘└─
doc └───┘ └┘ └┘ └─
txt └───┘ └┘ └┘ └─
par └───┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └───────────────┘└───────────┘└────────────┘┴└
1369
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
1370 /- scanr -/
src ────────────
typ ────────────
doc ────────────
txt ────────────
par ────────────
pid ────────────
st ────────────
1371
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1372 @[simp] theorem scanr_nil (f : α → β → β) (b : β) : scanr f b [] = [b] := rfl
id ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴ ┴┴┴ └─┘
src └───┘ └┘ ┴ ┴ ┴ └─┘
typ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴ ┴┴┴ └─┘
doc └──┘ └───┘
1373
1374 @[simp] theorem scanr_aux_cons (f : α → β → β) (b : β) : ∀ (a : α) (l : list α),
id ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1375 scanr_aux f b (a::l) = (foldr f b (a::l), scanr f b l)
id └───────┘ ┴ ┴ ┴└┘┴ ┴ ┴└───┘ ┴ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴
src └───────┘ └┘ ┴ ┴└───┘ └┘ └───┘
typ └───────┘ ┴ ┴ ┴└┘┴ ┴ ┴└───┘ ┴ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴
doc └───┘
1376 | a [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1377 | a (x::l) := let t := scanr_aux_cons x l in
id ┴└┘┴ ┴ └────────────┘
src └┘
typ ┴└┘┴ ┴ └────────────┘
1378 by simp only [scanr, scanr_aux, t, foldr_cons]
id └───┘ └───────┘ ┴ └────────┘
src └─────────┘└───┘└┘└───────┘└┘ └┘└────────┘└─
typ └─────────┘└───┘└┘└───────┘└┘┴└┘└────────┘└─
doc └─────────┘└───┘└┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────
1379
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1380 @[simp] theorem scanr_cons (f : α → β → β) (b : β) (a : α) (l : list α) :
id ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1381 scanr f b (a::l) = foldr f b (a::l) :: scanr f b l :=
id └───┘ ┴ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴ ┴└┘┴ └┘ └───┘ ┴ ┴ ┴
src └───┘ └┘ ┴ └───┘ └┘ └┘ └───┘
typ └───┘ ┴ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴ ┴└┘┴ └┘ └───┘ ┴ ┴ ┴
doc └───┘ └───┘
1382 by simp only [scanr, scanr_aux_cons, foldr_cons]; split; refl
id └───┘ └────────────┘ └────────┘
src └─────────┘└───┘└┘└────────────┘└┘└────────┘┴ └───┘ └────
typ └─────────┘└───┘└┘└────────────┘└┘└────────┘┴ └───┘ └────
doc └─────────┘└───┘└┘ └┘ ┴ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ └───┘ └────
par └─────────┘ └┘ └┘ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ └
st └───────────────────────────────────────────────────────────
1383
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1384 section foldl_eq_foldr
1385 -- foldl and foldr coincide when f is commutative and associative
1386 variables {f : α → α → α} (hcomm : commutative f) (hassoc : associative f)
id └─────────┘ └─────────┘
src └─────────┘ └─────────┘
typ └─────────┘ └─────────┘
1387
1388 include hassoc
1389 theorem foldl1_eq_foldr1 : ∀ a b l, foldl f a (l++[b]) = foldr f b (a::l)
id ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴┴┴ ┴ └───┘ ┴ ┴ ┴└┘┴
src └───┘ └┘┴ ┴ ┴ └───┘ └┘
typ ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴┴┴ ┴ └───┘ ┴ ┴ ┴└┘┴
1390 | a b nil := rfl
id └─┘ └─┘
src └─┘ └─┘
typ └─┘ └─┘
1391 | a b (c :: l) := by simp only [cons_append, foldl_cons, foldr_cons, foldl1_eq_foldr1 _ _ l]; rw hassoc
id └┘ └─────────┘ └────────┘ └────────┘ └──────────────┘ ┴ └────┘
src └┘ └─────────┘└─────────┘└┘└────────┘└┘└────────┘└┘ └───┘ ┴ └─┘ └
typ └┘ └─────────┘└─────────┘└┘└────────┘└┘└────────┘└┘└──────────────┘└───┘┴┴ └─┘└────┘└
doc └─────────┘ └┘ └┘ └┘ └───┘ ┴ └─┘ └
txt └─────────┘ └┘ └┘ └┘ └───┘ ┴ └─┘ └
par └─────────┘ └┘ └┘ └┘ └───┘ ┴ └─┘ └
pid ┴└──┘└┘ └┘ └┘ └┘ └───┘ ┴ ┴ └
st └───────────────────────────────────────────────────────────────────────────┘└────┘└
1392
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
1393 include hcomm
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
1394 theorem foldl_eq_of_comm_of_assoc : ∀ a b l, foldl f a (b::l) = f b (foldl f a l)
id ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └───┘ └┘ ┴ └───┘
typ ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
1395 | a b nil := hcomm a b
id ┴ ┴ └─┘ └───┘
src └─┘
typ ┴ ┴ └─┘ └───┘
1396 | a b (c::l) := by simp only [foldl_cons];
id └┘ └────────┘
src └┘ └─────────┘└────────┘┴
typ └┘ └─────────┘└────────┘┴
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid ┴└──┘└┘ ┴
st └────────────────────────
1397 rw [← foldl_eq_of_comm_of_assoc, right_comm _ hcomm hassoc]; refl
id └───────────────────────┘ └────────┘ └───┘ └────┘
src └────┘ └┘└────────┘└─┘ ┴ ┴ └────
typ └────┘└───────────────────────┘└┘└────────┘└─┘└───┘┴└────┘┴ └────
doc └────┘ └┘ └─┘ ┴ ┴ └────
txt └────┘ └┘ └─┘ ┴ ┴ └────
par └────┘ └┘ └─┘ ┴ ┴ └────
pid └──┘ └┘ └─┘ ┴ ┴ └
st ───────┘└─────────────────────────┘└─────────────────────────┘┴└──────
1398
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
1399 theorem foldl_eq_foldr : ∀ a l, foldl f a l = foldr f a l
id ┴ ┴ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src ─┘ └───┘ ┴ └───┘
typ ─┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
1400 | a nil := rfl
id └─┘ └─┘
src └─┘ └─┘
typ └─┘ └─┘
1401 | a (b :: l) :=
id └┘
src └┘
typ └┘
1402 by simp only [foldr_cons, foldl_eq_of_comm_of_assoc hcomm hassoc]; rw (foldl_eq_foldr a l)
id └────────┘ └───────────────────────┘ └───┘ └────┘ └────────────┘ ┴ ┴
src └─────────┘└────────┘└┘└───────────────────────┘┴ ┴ ┴ └─┘ ┴ ┴ └─
typ └─────────┘└────────┘└┘└───────────────────────┘┴└───┘┴└────┘┴ └─┘ └────────────┘┴┴┴┴└─
doc └─────────┘ └┘ ┴ ┴ ┴ └─┘ ┴ ┴ └─
txt └─────────┘ └┘ ┴ ┴ ┴ └─┘ ┴ ┴ └─
par └─────────┘ └┘ ┴ ┴ ┴ └─┘ ┴ ┴ └─
pid ┴└──┘└┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└
st └──────────────────────────────────────────────────────────────────┘┴└───────────────────
1403
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1404 end foldl_eq_foldr
1405
1406 section foldl_eq_foldlr'
1407
1408 variables {f : α → β → α}
1409 variables hf : ∀ a b c, f (f a b) c = f (f a c) b
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1410 include hf
1411
1412 theorem foldl_eq_of_comm' : ∀ a b l, foldl f a (b::l) = f (foldl f a l) b
id ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴
src └───┘ └┘ ┴ └───┘
typ ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴
1413 | a b [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1414 | a b (c :: l) := by rw [foldl,foldl,foldl,← foldl_eq_of_comm',foldl,hf]
id └┘ └───┘ └───┘ └───┘ └───────────────┘ └───┘ └┘
src └┘ └──┘└───┘┴└───┘┴└───┘└─┘ ┴└───┘┴ └─
typ └┘ └──┘└───┘┴└───┘┴└───┘└─┘└───────────────┘┴└───┘┴└┘└─
doc └──┘ ┴ ┴ └─┘ ┴ ┴ └─
txt └──┘ ┴ ┴ └─┘ ┴ ┴ └─
par └──┘ ┴ ┴ └─┘ ┴ ┴ └─
pid └┘ ┴ ┴ └─┘ ┴ ┴ ┴└
st └────────┘└────┘└────┘└──────────────────┘└────┘└─┘┴└
1415
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
1416 theorem foldl_eq_foldr' : ∀ a l, foldl f a l = foldr (flip f) a l
id ┴ ┴ └───┘ ┴ ┴ ┴ ┴ └───┘ └──┘ ┴ ┴ ┴
src ─┘ └───┘ ┴ └───┘ └──┘
typ ─┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ └───┘ └──┘ ┴ ┴ ┴
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
1417 | a [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1418 | a (b :: l) := by rw [foldl_eq_of_comm' hf,foldr,foldl_eq_foldr']; refl
id └┘ └───────────────┘ └┘ └───┘ └─────────────┘
src └┘ └──┘└───────────────┘┴ ┴└───┘┴ ┴ └────
typ └┘ └──┘└───────────────┘┴└┘┴└───┘┴└─────────────┘┴ └────
doc └──┘ ┴ ┴ ┴ ┴ └────
txt └──┘ ┴ ┴ ┴ ┴ └────
par └──┘ ┴ ┴ ┴ ┴ └────
pid └┘ ┴ ┴ ┴ ┴ └
st └───────────────────────┘└────┘└──────────────┘┴└──────
1419
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1420 end foldl_eq_foldlr'
1421
1422 section foldl_eq_foldlr'
1423
1424 variables {f : α → β → β}
1425 variables hf : ∀ a b c, f a (f b c) = f b (f a c)
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1426 include hf
1427
1428 theorem foldr_eq_of_comm' : ∀ a b l, foldr f a (b::l) = foldr f (f b a) l
id ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
src └───┘ └┘ ┴ └───┘
typ ┴ ┴ ┴ └───┘ ┴ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
1429 | a b [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1430 | a b (c :: l) := by rw [foldr,foldr,foldr,hf,← foldr_eq_of_comm']; refl
id └┘ └───┘ └───┘ └───┘ └┘ └───────────────┘
src └┘ └──┘└───┘┴└───┘┴└───┘┴ └─┘ ┴ └────
typ └┘ └──┘└───┘┴└───┘┴└───┘┴└┘└─┘└───────────────┘┴ └────
doc └──┘ ┴ ┴ ┴ └─┘ ┴ └────
txt └──┘ ┴ ┴ ┴ └─┘ ┴ └────
par └──┘ ┴ ┴ ┴ └─┘ ┴ └────
pid └┘ ┴ ┴ ┴ └─┘ ┴ └
st └────────┘└────┘└────┘└─┘└──────────────────┘┴└──────
1431
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1432 end foldl_eq_foldlr'
1433
1434 section
1435 variables {op : α → α → α} [ha : is_associative α op] [hc : is_commutative α op]
id └────────────┘ └────────────┘
src └────────────┘ └────────────┘
typ └────────────┘ └────────────┘
1436 local notation a * b := op a b
1437 local notation l <*> a := foldl op a l
id └───┘
src └───┘
typ └───┘
1438
1439 include ha
1440
1441 lemma foldl_assoc : ∀ {l : list α} {a₁ a₂}, l <*> (a₁ * a₂) = a₁ * (l <*> a₂)
id ┴ └──┘ ┴ └┘ └┘ ┴ └─┘ └┘ ┴ └┘ ┴ └┘ ┴ ┴ └─┘ └┘
src └──┘ └─┘ ┴ └─┘
typ ┴ └──┘ ┴ └┘ └┘ ┴ └─┘ └┘ ┴ └┘ ┴ └┘ ┴ ┴ └─┘ └┘
1442 | [] a₁ a₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1443 | (a :: l) a₁ a₂ :=
id ┴ └┘ ┴ └┘ └┘
src └┘
typ ┴ └┘ ┴ └┘ └┘
1444 calc a::l <*> (a₁ * a₂) = l <*> (a₁ * (a₂ * a)) : by simp only [foldl_cons, ha.assoc]
id └┘ └─┘ ┴ └─┘ ┴ ┴ └────────┘
src └┘ └─┘ └─┘ └─────────┘└────────┘└┘ └─
typ └┘ └─┘ ┴ └─┘ ┴ ┴ └─────────┘└────────┘└┘└──────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └─────────────────────────────────
1445 ... = a₁ * (a::l <*> a₂) : by rw [foldl_assoc, foldl_cons]
id ┴ └┘ └─┘ └────────┘
src ───┘ └┘ └─┘ └──┘ └┘└────────┘└─
typ ───┘ ┴ └┘ └─┘ └──┘└─────────┘└┘└────────┘└─
doc ───┘ └──┘ └┘ └─
txt ───┘ └──┘ └┘ └─
par ───┘ └──┘ └┘ └─
pid ───┘ └┘ └┘ ┴└
st ───┘ └──────────────┘└──────────┘┴└
1446
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1447 lemma foldl_op_eq_op_foldr_assoc : ∀{l : list α} {a₁ a₂}, (l <*> a₁) * a₂ = a₁ * l.foldr (*) a₂
id ┴ └──┘ ┴ └┘ └┘ ┴ └─┘ └┘ ┴ └┘ ┴ └┘ ┴ ┴└────┘ ┴ └┘
src └──┘ └─┘ ┴ └────┘
typ ┴ └──┘ ┴ └┘ └┘ ┴ └─┘ └┘ ┴ └┘ ┴ └┘ ┴ ┴└────┘ ┴ └┘
1448 | [] a₁ a₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1449 | (a :: l) a₁ a₂ := by simp only [foldl_cons, foldr_cons, foldl_assoc, ha.assoc]; rw [foldl_op_eq_op_foldr_assoc]
id └┘ └────────┘ └────────┘ └─────────┘
src └┘ └─────────┘└────────┘└┘└────────┘└┘└─────────┘└┘ ┴ └──┘ └─
typ └┘ └─────────┘└────────┘└┘└────────┘└┘└─────────┘└┘└──────┘┴ └──┘└────────────────────────┘└─
doc └─────────┘ └┘ └┘ └┘ ┴ └──┘ └─
txt └─────────┘ └┘ └┘ └┘ ┴ └──┘ └─
par └─────────┘ └┘ └┘ └┘ ┴ └──┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ └┘ ┴└
st └──────────────────────────────────────────────────────────────┘└────────────────────────┘┴└
1450
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1451 include hc
1452
1453 lemma foldl_assoc_comm_cons {l : list α} {a₁ a₂} : (a₁ :: l) <*> a₂ = a₁ * (l <*> a₂) :=
id └──┘ ┴ └┘ └┘ ┴ └─┘ └┘ ┴ └┘ ┴ ┴ └─┘ └┘
src └──┘ └┘ └─┘ ┴ └─┘
typ └──┘ ┴ └┘ └┘ ┴ └─┘ └┘ ┴ └┘ ┴ ┴ └─┘ └┘
1454 by rw [foldl_cons, hc.comm, foldl_assoc]
id └────────┘ └─────────┘
src └──┘└────────┘└┘ └┘└─────────┘└─
typ └──┘└────────┘└┘└─────┘└┘└─────────┘└─
doc └──┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └─────────────┘└───────┘└───────────┘┴└
1455
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1456 end
1457
1458 /- mfoldl, mfoldr -/
1459
1460 section mfoldl_mfoldr
1461 variables {m : Type v → Type w} [monad m]
id └──┘ └───┘
src └───┘
typ └──┘ └───┘
1462
1463 @[simp] theorem mfoldl_nil (f : β → α → m β) {b} : mfoldl f b [] = pure b := rfl
id ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ └──┘ ┴ └─┘
src └────┘ └┘ ┴ └──┘ └─┘
typ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ └──┘ ┴ └─┘
doc └──┘
1464
1465 @[simp] theorem mfoldr_nil (f : α → β → m β) {b} : mfoldr f b [] = pure b := rfl
id ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ └──┘ ┴ └─┘
src └────┘ └┘ ┴ └──┘ └─┘
typ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ └──┘ ┴ └─┘
doc └──┘
1466
1467 @[simp] theorem mfoldl_cons {f : β → α → m β} {b a l} :
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
doc └──┘
1468 mfoldl f b (a :: l) = f b a >>= λ b', mfoldl f b' l := rfl
id └────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └─┘ └┘ └────┘ ┴ └┘ ┴ └─┘
src └────┘ └┘ ┴ └─┘ └────┘ └─┘
typ └────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └─┘ └┘ └────┘ ┴ └┘ ┴ └─┘
1469
1470 @[simp] theorem mfoldr_cons {f : α → β → m β} {b a l} :
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
doc └──┘
1471 mfoldr f b (a :: l) = mfoldr f b l >>= f a := rfl
id └────┘ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘
src └────┘ └┘ ┴ └────┘ └─┘ └─┘
typ └────┘ ┴ ┴ ┴ └┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘
1472
1473 variables [is_lawful_monad m]
id └─────────────┘
src └─────────────┘
typ └─────────────┘
1474
1475 @[simp] theorem mfoldl_append {f : β → α → m β} : ∀ {b l₁ l₂},
id ┴ ┴ ┴ ┴ ┴┴ └┘ └┘
typ ┴ ┴ ┴ ┴ ┴┴ └┘ └┘
doc └──┘
1476 mfoldl f b (l₁ ++ l₂) = mfoldl f b l₁ >>= λ x, mfoldl f x l₂
id └────┘ ┴ ┴ └┘ └┘ └┘ ┴ └────┘ ┴ ┴ └┘ └─┘ ┴ └────┘ ┴ ┴ └┘
src └────┘ └┘ ┴ └────┘ └─┘ └────┘
typ └────┘ ┴ ┴ └┘ └┘ └┘ ┴ └────┘ ┴ ┴ └┘ └─┘ ┴ └────┘ ┴ ┴ └┘
1477 | _ [] _ := by simp only [nil_append, mfoldl_nil, pure_bind]
id └┘ └────────┘ └────────┘ └───────┘
src └┘ └─────────┘└────────┘└┘└────────┘└┘└───────┘└┘
typ └┘ └─────────┘└────────┘└┘└────────┘└┘└───────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st └─────────────────────────────────────────────┘
1478 | _ (_::_) _ := by simp only [cons_append, mfoldl_cons, mfoldl_append, bind_assoc]
id └┘ └─────────┘ └─────────┘ └────────┘
src └┘ └─────────┘└─────────┘└┘└─────────┘└┘ └┘└────────┘└─
typ └┘ └─────────┘└─────────┘└┘└─────────┘└┘└───────────┘└┘└────────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────
1479
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1480 @[simp] theorem mfoldr_append {f : α → β → m β} : ∀ {b l₁ l₂},
id ┴ ┴ ┴ ┴ ┴┴ └┘ └┘
typ ┴ ┴ ┴ ┴ ┴┴ └┘ └┘
doc └──┘
1481 mfoldr f b (l₁ ++ l₂) = mfoldr f b l₂ >>= λ x, mfoldr f x l₁
id └────┘ ┴ ┴ └┘ └┘ └┘ ┴ └────┘ ┴ ┴ └┘ └─┘ ┴ └────┘ ┴ ┴ └┘
src └────┘ └┘ ┴ └────┘ └─┘ └────┘
typ └────┘ ┴ ┴ └┘ └┘ └┘ ┴ └────┘ ┴ ┴ └┘ └─┘ ┴ └────┘ ┴ ┴ └┘
1482 | _ [] _ := by simp only [nil_append, mfoldr_nil, bind_pure]
id └┘ └────────┘ └────────┘ └───────┘
src └┘ └─────────┘└────────┘└┘└────────┘└┘└───────┘└┘
typ └┘ └─────────┘└────────┘└┘└────────┘└┘└───────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st └─────────────────────────────────────────────┘
1483 | _ (_::_) _ := by simp only [mfoldr_cons, cons_append, mfoldr_append, bind_assoc]
id └┘ └─────────┘ └─────────┘ └────────┘
src └┘ └─────────┘└─────────┘└┘└─────────┘└┘ └┘└────────┘└─
typ └┘ └─────────┘└─────────┘└┘└─────────┘└┘└───────────┘└┘└────────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────
1484
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1485 end mfoldl_mfoldr
1486
1487 /- prod and sum -/
1488
1489 -- list.sum was already defined in defs.lean, but we couldn't tag it with `to_additive` yet.
1490 attribute [to_additive] list.prod
id └───────┘
src └───────┘
typ └───────┘
doc └─────────┘ └───────┘
1491
1492 section monoid
1493 variables [monoid α] {l l₁ l₂ : list α} {a : α}
id └────┘ └──┘
src └────┘ └──┘
typ └────┘ └──┘
1494
1495 @[simp, to_additive]
doc └──┘ └─────────┘
1496 theorem prod_nil : ([] : list α).prod = 1 := rfl
id └┘ └──┘ ┴ └──┘ ┴ └─┘
src └┘ └──┘ └──┘ ┴ └─┘
typ └┘ └──┘ ┴ └──┘ ┴ └─┘
doc └──┘
1497
1498 @[simp, to_additive]
doc └──┘ └─────────┘
1499 theorem prod_cons : (a::l).prod = a * l.prod :=
id ┴└┘┴ └──┘ ┴ ┴ ┴ ┴└───┘
src └┘ └──┘ ┴ ┴ └───┘
typ ┴└┘┴ └──┘ ┴ ┴ ┴ ┴└───┘
doc └──┘ └───┘
1500 calc (a::l).prod = foldl (*) (a * 1) l : by simp only [list.prod, foldl_cons, one_mul, mul_one]
id ┴└┘┴ └──┘ └───┘ ┴ ┴ ┴ ┴ └───────┘ └────────┘ └─────┘ └─────┘
src └┘ └──┘ └───┘ ┴ ┴ └─────────┘└───────┘└┘└────────┘└┘└─────┘└┘└─────┘└─
typ ┴└┘┴ └──┘ └───┘ ┴ ┴ ┴ ┴ └─────────┘└───────┘└┘└────────┘└┘└─────┘└┘└─────┘└─
doc └──┘ └─────────┘└───────┘└┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────
1501 ... = _ : foldl_assoc
id └─────────┘
src ─┘ └─────────┘
typ ─┘ └─────────┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
1502
1503 @[simp, to_additive]
doc └──┘ └─────────┘
1504 theorem prod_append : (l₁ ++ l₂).prod = l₁.prod * l₂.prod :=
id └┘ └┘ └┘ └──┘ ┴ └┘└───┘ ┴ └┘└───┘
src └┘ └──┘ ┴ └───┘ ┴ └───┘
typ └┘ └┘ └┘ └──┘ ┴ └┘└───┘ ┴ └┘└───┘
doc └──┘ └───┘ └───┘
1505 calc (l₁ ++ l₂).prod = foldl (*) (foldl (*) 1 l₁ * 1) l₂ : by simp [list.prod]
id └┘ └┘ └┘ └──┘ └───┘ ┴ └───┘ ┴ └┘ ┴ └┘ └───────┘
src └┘ └──┘ └───┘ ┴ └───┘ ┴ ┴ └────┘└───────┘└─
typ └┘ └┘ └┘ └──┘ └───┘ ┴ └───┘ ┴ └┘ ┴ └┘ └────┘└───────┘└─
doc └──┘ └────┘└───────┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └─────────────────
1506 ... = l₁.prod * l₂.prod : foldl_assoc
id └┘└───┘ ┴ └┘└───┘ └─────────┘
src ─┘ └───┘ ┴ └───┘ └─────────┘
typ ─┘ └┘└───┘ ┴ └┘└───┘ └─────────┘
doc ─┘ └───┘ └───┘
txt ─┘
par ─┘
pid ─┘
st ─┘
1507
1508 @[simp, to_additive]
doc └──┘ └─────────┘
1509 theorem prod_join {l : list (list α)} : l.join.prod = (l.map list.prod).prod :=
id └──┘ └──┘ ┴ ┴└───┘└───┘ ┴ ┴└──┘ └───────┘ └──┘
src └──┘ └──┘ └───┘└───┘ ┴ └──┘ └───────┘ └──┘
typ └──┘ └──┘ ┴ ┴└───┘└───┘ ┴ ┴└──┘ └───────┘ └──┘
doc └───┘ └───────┘ └──┘
1510 by induction l; [refl, simp only [*, list.join, map, prod_append, prod_cons]]
id ┴ ┴ └───────┘ └─┘ └─────────┘ └───────┘
src └────────┘ ┴└──┘ └────────────┘└───────┘└┘└─┘└┘└─────────┘└┘└───────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└───────┘└┘└─┘└┘└─────────┘└┘└───────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ └┘ ┴
st └─────────────────────────────────────────────────────────────────────────┘
1511
1512 @[to_additive]
doc └─────────┘
1513 theorem prod_hom_rel {α β γ : Type*} [monoid β] [monoid γ] (l : list α) {r : β → γ → Prop}
id └────┘ ┴ └────┘ ┴ └──┘ ┴ ┴ ┴
src └────┘ └────┘ └──┘
typ └────┘ ┴ └────┘ ┴ └──┘ ┴ ┴ ┴
1514 {f : α → β} {g : α → γ} (h₁ : r 1 1) (h₂ : ∀⦃a b c⦄, r b c → r (f a * b) (g a * c)) :
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1515 r (l.map f).prod (l.map g).prod :=
id ┴ ┴└──┘ ┴ └──┘ ┴└──┘ ┴ └──┘
src └──┘ └──┘ └──┘ └──┘
typ ┴ ┴└──┘ ┴ └──┘ ┴└──┘ ┴ └──┘
doc └──┘ └──┘
1516 list.rec_on l h₁ (λ a l hl, by simp only [map_cons, prod_cons, h₂ hl])
id └─────────┘ ┴ └┘ ┴ ┴ └┘ └──────┘ └───────┘ └┘ └┘
src └─────────┘ └─────────┘└──────┘└┘└───────┘└┘ ┴ ┴
typ └─────────┘ ┴ └┘ ┴ ┴ └┘ └─────────┘└──────┘└┘└───────┘└┘└┘┴└┘┴
doc └─────────┘ └┘ └┘ ┴ ┴
txt └─────────┘ └┘ └┘ ┴ ┴
par └─────────┘ └┘ └┘ ┴ ┴
pid ┴└──┘└┘ └┘ └┘ ┴ ┴
st └─────────────────────────────────────┘
1517
1518 @[to_additive]
doc └─────────┘
1519 theorem prod_hom [monoid β] (l : list α) (f : α → β) [is_monoid_hom f] :
id └────┘ ┴ └──┘ ┴ ┴ ┴ └───────────┘ ┴
src └────┘ └──┘ └───────────┘
typ └────┘ ┴ └──┘ ┴ ┴ ┴ └───────────┘ ┴
doc └───────────┘
1520 (l.map f).prod = f l.prod :=
id ┴└──┘ ┴ └──┘ ┴ ┴ ┴└───┘
src └──┘ └──┘ ┴ └───┘
typ ┴└──┘ ┴ └──┘ ┴ ┴ ┴└───┘
doc └──┘ └───┘
1521 by { simp only [prod, foldl_map, (is_monoid_hom.map_one f).symm],
id └──┘ └───────┘ └───────────────────┘ ┴
src └─────────┘└──┘└┘└───────┘└┘ └───────────────────┘┴ └─────┘
typ └─────────┘└──┘└┘└───────┘└┘ └───────────────────┘┴┴└─────┘
doc └─────────┘└──┘└┘ └┘ ┴ └─────┘
txt └─────────┘ └┘ └┘ ┴ └─────┘
par └─────────┘ └┘ └┘ ┴ └─────┘
pid ┴└──┘└┘ └┘ └┘ ┴ └─────┘
st └────────────────────────────────────────────────────────────┘└─
1522 exact l.foldl_hom _ _ _ 1 (is_monoid_hom.map_mul f) }
id └─────────┘ └───────────────────┘ ┴
src └────┘└─────────┘└───────┘ └───────────────────┘┴ └┘
typ └────┘└─────────┘└───────┘ └───────────────────┘┴┴└┘
doc └────┘ └───────┘ └───────────────────┘┴ └┘
txt └────┘ └───────┘ ┴ └┘
par └────┘ └───────┘ ┴ └┘
pid ┴ └───────┘ ┴ ┴┴
st ─────────────────────────────────────────────────────┘└┘
1523
1524 end monoid
1525
1526 @[simp, to_additive]
doc └──┘ └─────────┘
1527 theorem prod_erase [decidable_eq α] [comm_monoid α] {a} :
id └──────────┘ ┴ └─────────┘ ┴
src └──────────┘ └─────────┘
typ └──────────┘ ┴ └─────────┘ ┴
1528 Π {l : list α}, a ∈ l → a * (l.erase a).prod = l.prod
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└────┘ ┴ └──┘ ┴ ┴└───┘
src └──┘ ┴ ┴ └────┘ └──┘ ┴ └───┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└────┘ ┴ └──┘ ┴ ┴└───┘
doc └──┘ └───┘
1529 | (b::l) h :=
id └┘
src └┘
typ └┘
1530 begin
st └─────
1531 rcases eq_or_ne_mem_of_mem h with rfl | ⟨ne, h⟩,
id └─────────────────┘ ┴
src └─────┘└─────────────────┘┴ └─────────────────┘
typ └─────┘└─────────────────┘┴┴└─────────────────┘
doc └─────┘ ┴ └─────────────────┘
txt └─────┘ ┴ └─────────────────┘
par └─────┘ ┴ └─────────────────┘
pid ┴ ┴ └─────────────────┘
st ──────────────────────────────────────────────────┘└─
1532 { simp only [list.erase, if_pos, prod_cons] },
id └────────┘ └────┘ └───────┘
src └─────────┘└────────┘└┘└────┘└┘└───────┘└┘
typ └─────────┘└────────┘└┘└────┘└┘└───────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st ─────┘└────────────────────────────────────────┘└┘└
1533 { simp only [list.erase, if_neg (mt eq.symm ne), prod_cons, prod_erase h, mul_left_comm a b] }
id └────────┘ └────┘ └┘ └─────┘ └┘ └───────┘ └────────┘ ┴ └───────────┘ ┴ ┴
src └─────────┘└────────┘└┘└────┘┴ └┘┴└─────┘┴└┘└─┘└───────┘└┘ ┴ └┘└───────────┘┴ ┴ └┘
typ └─────────┘└────────┘└┘└────┘┴ └┘┴└─────┘┴└┘└─┘└───────┘└┘└────────┘┴┴└┘└───────────┘┴┴┴┴└┘
doc └─────────┘ └┘ ┴ ┴ ┴ └─┘ └┘ ┴ └┘ ┴ ┴ └┘
txt └─────────┘ └┘ ┴ ┴ ┴ └─┘ └┘ ┴ └┘ ┴ ┴ └┘
par └─────────┘ └┘ ┴ ┴ ┴ └─┘ └┘ ┴ └┘ ┴ ┴ └┘
pid ┴└──┘└┘ └┘ ┴ ┴ ┴ └─┘ └┘ ┴ └┘ ┴ ┴ ┴┴
st ────────────────────────────────────────────────────────────────────────────────────────────────┘└─
1534 end
st ────┘
1535
1536 lemma dvd_prod [comm_semiring α] {a} {l : list α} (ha : a ∈ l) : a ∣ l.prod :=
id └───────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└───┘
src └───────────┘ └──┘ ┴ ┴ └───┘
typ └───────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└───┘
doc └───┘
1537 let ⟨s, t, h⟩ := mem_split ha in
id └─┘ └───────┘ └┘
src └───────┘
typ └─┘ └───────┘ └┘
1538 by rw [h, prod_append, prod_cons, mul_left_comm]; exact dvd_mul_right _ _
id ┴ └─────────┘ └───────┘ └───────────┘ └───────────┘
src └──┘ └┘└─────────┘└┘└───────┘└┘└───────────┘┴ └────┘└───────────┘└────
typ └──┘┴└┘└─────────┘└┘└───────┘└┘└───────────┘┴ └────┘└───────────┘└────
doc └──┘ └┘ └┘ └┘ ┴ └────┘ └────
txt └──┘ └┘ └┘ └┘ ┴ └────┘ └────
par └──┘ └┘ └┘ └┘ ┴ └────┘ └────
pid └┘ └┘ └┘ └┘ ┴ ┴ └──┘└
st └────┘└───────────┘└─────────┘└─────────────┘┴└─────────────────────────
1539
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1540 @[simp] theorem sum_const_nat (m n : ℕ) : sum (list.repeat m n) = m * n :=
id ┴ └─┘ └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └─┘ └─────────┘ ┴ ┴
typ ┴ └─┘ └─────────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └─┘
1541 by induction n; [refl, simp only [*, repeat_succ, sum_cons, nat.mul_succ, add_comm]]
id ┴ ┴ └─────────┘ └──────┘ └──────────┘ └──────┘
src └────────┘ ┴└──┘ └────────────┘└─────────┘└┘└──────┘└┘└──────────┘└┘└──────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└─────────┘└┘└──────┘└┘└──────────┘└┘└──────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ └┘ ┴
st └────────────────────────────────────────────────────────────────────────────────┘
1542
1543 theorem dvd_sum [comm_semiring α] {a} {l : list α} (h : ∀ x ∈ l, a ∣ x) : a ∣ l.sum :=
id └───────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴└──┘
src └───────────┘ └──┘ ┴ ┴ └──┘
typ └───────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴└──┘
doc └──┘
1544 begin
st └─────
1545 induction l with x l ih,
id ┴
src └────────┘ └──────────┘
typ └────────┘┴└──────────┘
doc └────────┘ └──────────┘
txt └────────┘ └──────────┘
par └────────┘ └──────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─
1546 { exact dvd_zero _ },
id └──────┘
src └────┘└──────┘└─┘
typ └────┘└──────┘└─┘
doc └────┘ └─┘
txt └────┘ └─┘
par └────┘ └─┘
pid ┴ └┘┴
st ───┘└───────────────┘└┘└
1547 { rw [list.sum_cons],
id └───────────┘
src └──┘└───────────┘┴
typ └──┘└───────────┘┴
doc └──┘ ┴
txt └──┘ ┴
par └──┘ ┴
pid └┘ ┴
st ────────────────────┘┴└─
1548 exact dvd_add (h _ (mem_cons_self _ _)) (ih (λ x hx, h x (mem_cons_of_mem _ hx))) }
id └─────┘ └───────────┘ └┘ ┴ └─────────────┘
src └────┘└─────┘┴ └─┘ └───────────┘└─────┘ ┴ └─────┘ ┴ ┴ └─────────────┘└─┘ └──┘
typ └────┘└─────┘┴ └─┘ └───────────┘└─────┘ └┘┴ └─────┘┴┴ ┴ └─────────────┘└─┘ └──┘
doc └────┘ ┴ └─┘ └─────┘ ┴ └─────┘ ┴ ┴ └─┘ └──┘
txt └────┘ ┴ └─┘ └─────┘ ┴ └─────┘ ┴ ┴ └─┘ └──┘
par └────┘ ┴ └─┘ └─────┘ ┴ └─────┘ ┴ ┴ └─┘ └──┘
pid ┴ ┴ └─┘ └─────┘ ┴ └─────┘ ┴ ┴ └─┘ └─┘┴
st ─────────────────────────────────────────────────────────────────────────────────────┘└─
1549 end
st ──┘
1550
1551 @[simp] theorem length_join (L : list (list α)) : length (join L) = sum (map length L) :=
id └──┘ └──┘ ┴ └────┘ └──┘ ┴ ┴ └─┘ └─┘ └────┘ ┴
src └──┘ └──┘ └────┘ └──┘ ┴ └─┘ └─┘ └────┘
typ └──┘ └──┘ ┴ └────┘ └──┘ ┴ ┴ └─┘ └─┘ └────┘ ┴
doc └──┘ └─┘
1552 by induction L; [refl, simp only [*, join, map, sum_cons, length_append]]
id ┴ ┴ └──┘ └─┘ └──────┘ └───────────┘
src └────────┘ ┴└──┘ └────────────┘└──┘└┘└─┘└┘└──────┘└┘└───────────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└──┘└┘└─┘└┘└──────┘└┘└───────────┘┴
doc └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ └┘ └┘ ┴
st └─────────────────────────────────────────────────────────────────────┘
1553
1554 @[simp] theorem length_bind (l : list α) (f : α → list β) : length (list.bind l f) = sum (map (length ∘ f) l) :=
id └──┘ ┴ ┴ └──┘ ┴ └────┘ └───────┘ ┴ ┴ ┴ └─┘ └─┘ └────┘ ┴ ┴ ┴
src └──┘ └──┘ └────┘ └───────┘ ┴ └─┘ └─┘ └────┘ ┴
typ └──┘ ┴ ┴ └──┘ ┴ └────┘ └───────┘ ┴ ┴ ┴ └─┘ └─┘ └────┘ ┴ ┴ ┴
doc └──┘ └─┘
1555 by rw [list.bind, length_join, map_map]
id └───────┘ └─────────┘ └─────┘
src └──┘└───────┘└┘└─────────┘└┘└─────┘└─
typ └──┘└───────┘└┘└─────────┘└┘└─────┘└─
doc └──┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └────────────┘└───────────┘└───────┘┴└
1556
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1557 lemma exists_lt_of_sum_lt [decidable_linear_ordered_cancel_comm_monoid β] {l : list α}
id └─────────────────────────────────────────┘ ┴ └──┘ ┴
src └─────────────────────────────────────────┘ └──┘
typ └─────────────────────────────────────────┘ ┴ └──┘ ┴
1558 (f g : α → β) (h : (l.map f).sum < (l.map g).sum) : ∃ x ∈ l, f x < g x :=
id ┴ ┴ ┴└──┘ ┴ └─┘ ┴ ┴└──┘ ┴ └─┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └─┘ ┴ └──┘ └─┘ ┴ ┴ ┴
typ ┴ ┴ ┴└──┘ ┴ └─┘ ┴ ┴└──┘ ┴ └─┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴
doc └─┘ └─┘
1559 begin
st └─────
1560 induction l with x l,
id ┴
src └────────┘ └───────┘
typ └────────┘┴└───────┘
doc └────────┘ └───────┘
txt └────────┘ └───────┘
par └────────┘ └───────┘
pid ┴ ┴└──────┘
st ─────────────────────┘└─
1561 { exfalso, exact lt_irrefl _ h },
id └───────┘ ┴
src └─────┘ └────┘└───────┘└─┘ ┴
typ └─────┘ └────┘└───────┘└─┘┴┴
doc └─────┘ └────┘ └─┘ ┴
txt └─────┘ └────┘ └─┘ ┴
par └─────┘ └────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ───┘└─────┘└────────────────────┘└┘└
1562 { by_cases h' : f x < g x, exact ⟨x, mem_cons_self _ _, h'⟩,
id ┴ ┴ ┴ ┴ ┴ └───────────┘ └┘
src └───────┘ └─┘ ┴ ┴┴┴ ┴ └────┘ └┘└───────────┘└────┘ ┴
typ └───────┘ └─┘┴┴ ┴┴┴┴┴┴ └────┘ ┴└┘└───────────┘└────┘└┘┴
doc └───────┘ └─┘ ┴ ┴ ┴ ┴ └────┘ └┘ └────┘ ┴
txt └───────┘ └─┘ ┴ ┴ ┴ ┴ └────┘ └┘ └────┘ ┴
par └───────┘ └─┘ ┴ ┴ ┴ ┴ └────┘ └┘ └────┘ ┴
pid ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └┘ └────┘ ┴
st ──────────────────────────┘└────────────────────────────────┘└─
1563 rcases l_ih _ with ⟨y, h1y, h2y⟩, refine ⟨y, mem_cons_of_mem x h1y, h2y⟩, simp at h,
id └──┘ ┴ └─────────────┘ ┴ └─┘ └─┘
src └─────┘ └───────────────────┘ └─────┘ └┘└─────────────┘┴ ┴ └┘ ┴ └───────┘
typ └─────┘└──┘└───────────────────┘ └─────┘ ┴└┘└─────────────┘┴┴┴└─┘└┘└─┘┴ └───────┘
doc └─────┘ └───────────────────┘ └─────┘ └┘ ┴ ┴ └┘ ┴ └───────┘
txt └─────┘ └───────────────────┘ └─────┘ └┘ ┴ ┴ └┘ ┴ └───────┘
par └─────┘ └───────────────────┘ └─────┘ └┘ ┴ ┴ └┘ ┴ └───────┘
pid ┴ └───────────────────┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴└──┘
st ───────────────────────────────────┘└──────────────────────────────────────┘└─────────┘└─
1564 exact lt_of_add_lt_add_left' (lt_of_lt_of_le h $ add_le_add_right (le_of_not_gt h') _) }
id └────────────────────┘ └────────────┘ ┴ └──────────────┘ └──────────┘ └┘
src └────┘└────────────────────┘┴ └────────────┘┴ ┴ ┴└──────────────┘┴ └──────────┘┴ └───┘
typ └────┘└────────────────────┘┴ └────────────┘┴┴┴ ┴└──────────────┘┴ └──────────┘┴└┘└───┘
doc └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───┘
txt └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───┘
par └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───┘
pid ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘┴
st ──────────────────────────────────────────────────────────────────────────────────────────┘└─
1565 end
st ──┘
1566
1567 lemma exists_le_of_sum_le [decidable_linear_ordered_cancel_comm_monoid β] {l : list α}
id └─────────────────────────────────────────┘ ┴ └──┘ ┴
src └─────────────────────────────────────────┘ └──┘
typ └─────────────────────────────────────────┘ ┴ └──┘ ┴
1568 (hl : l ≠ []) (f g : α → β) (h : (l.map f).sum ≤ (l.map g).sum) : ∃ x ∈ l, f x ≤ g x :=
id ┴ ┴ └┘ ┴ ┴ ┴└──┘ ┴ └─┘ ┴ ┴└──┘ ┴ └─┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴
src ┴ └┘ └──┘ └─┘ ┴ └──┘ └─┘ ┴ ┴ ┴
typ ┴ ┴ └┘ ┴ ┴ ┴└──┘ ┴ └─┘ ┴ ┴└──┘ ┴ └─┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴
doc └─┘ └─┘
1569 begin
st └─────
1570 cases l with x l,
id ┴
src └────┘ └───────┘
typ └────┘┴└───────┘
doc └────┘ └───────┘
txt └────┘ └───────┘
par └────┘ └───────┘
pid ┴ └───────┘
st ─────────────────┘└─
1571 { contradiction },
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid ┴
st ───┘└────────────┘└┘└
1572 { by_cases h' : f x ≤ g x, exact ⟨x, mem_cons_self _ _, h'⟩,
id ┴ ┴ ┴ ┴ ┴ └───────────┘ └┘
src └───────┘ └─┘ ┴ ┴┴┴ ┴ └────┘ └┘└───────────┘└────┘ ┴
typ └───────┘ └─┘┴┴ ┴┴┴┴┴┴ └────┘ ┴└┘└───────────┘└────┘└┘┴
doc └───────┘ └─┘ ┴ ┴ ┴ ┴ └────┘ └┘ └────┘ ┴
txt └───────┘ └─┘ ┴ ┴ ┴ ┴ └────┘ └┘ └────┘ ┴
par └───────┘ └─┘ ┴ ┴ ┴ ┴ └────┘ └┘ └────┘ ┴
pid ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └┘ └────┘ ┴
st ──────────────────────────┘└────────────────────────────────┘└─
1573 rcases exists_lt_of_sum_lt f g _ with ⟨y, h1y, h2y⟩,
id └─────────────────┘ ┴ ┴
src └─────┘└─────────────────┘┴ ┴ └───────────────────┘
typ └─────┘└─────────────────┘┴┴┴┴└───────────────────┘
doc └─────┘ ┴ ┴ └───────────────────┘
txt └─────┘ ┴ ┴ └───────────────────┘
par └─────┘ ┴ ┴ └───────────────────┘
pid ┴ ┴ ┴ └───────────────────┘
st ──────────────────────────────────────────────────────┘└─
1574 exact ⟨y, mem_cons_of_mem x h1y, le_of_lt h2y⟩, simp at h,
id ┴ └─────────────┘ ┴ └─┘ └──────┘ └─┘
src └────┘ └┘└─────────────┘┴ ┴ └┘└──────┘┴ ┴ └───────┘
typ └────┘ ┴└┘└─────────────┘┴┴┴└─┘└┘└──────┘┴└─┘┴ └───────┘
doc └────┘ └┘ ┴ ┴ └┘ ┴ ┴ └───────┘
txt └────┘ └┘ ┴ ┴ └┘ ┴ ┴ └───────┘
par └────┘ └┘ ┴ ┴ └┘ ┴ ┴ └───────┘
pid ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴└──┘
st ─────────────────────────────────────────────────┘└─────────┘└─
1575 exact lt_of_add_lt_add_left' (lt_of_le_of_lt h $ add_lt_add_right (lt_of_not_ge h') _) }
id └────────────────────┘ └────────────┘ ┴ └──────────────┘ └──────────┘ └┘
src └────┘└────────────────────┘┴ └────────────┘┴ ┴ ┴└──────────────┘┴ └──────────┘┴ └───┘
typ └────┘└────────────────────┘┴ └────────────┘┴┴┴ ┴└──────────────┘┴ └──────────┘┴└┘└───┘
doc └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───┘
txt └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───┘
par └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───┘
pid ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘┴
st ──────────────────────────────────────────────────────────────────────────────────────────┘└─
1576 end
st ──┘
1577
1578 /- lexicographic ordering -/
1579
1580 inductive lex (r : α → α → Prop) : list α → list α → Prop
id ┴ ┴ └──┘ └──┘
src └──┘ └──┘
typ ┴ ┴ └──┘ └──┘
1581 | nil {} {a l} : lex [] (a :: l)
id ┴ ┴ └┘ ┴ └┘ ┴
src └┘ └┘
typ ┴ ┴ └┘ ┴ └┘ ┴
1582 | cons {a l₁ l₂} (h : lex l₁ l₂) : lex (a :: l₁) (a :: l₂)
id ┴ └┘ └┘ └─┘ └┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘
src └┘ └┘
typ ┴ └┘ └┘ └─┘ └┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘
1583 | rel {a₁ l₁ a₂ l₂} (h : r a₁ a₂) : lex (a₁ :: l₁) (a₂ :: l₂)
id └┘ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘
src └┘ └┘
typ └┘ └┘ └┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘
1584
1585 namespace lex
1586 theorem cons_iff {r : α → α → Prop} [is_irrefl α r] {a l₁ l₂} :
id ┴ ┴ └───────┘ ┴ ┴
src └───────┘
typ ┴ ┴ └───────┘ ┴ ┴
1587 lex r (a :: l₁) (a :: l₂) ↔ lex r l₁ l₂ :=
id └─┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ └─┘ ┴ └┘ └┘
src └─┘ └┘ └┘ ┴ └─┘
typ └─┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ └─┘ ┴ └┘ └┘
1588 ⟨λ h, by cases h with _ _ _ _ _ h _ _ _ _ h;
id ┴ ┴
src └────┘ └─────────────────────────┘
typ ┴ └────┘┴└─────────────────────────┘
doc └────┘ └─────────────────────────┘
txt └────┘ └─────────────────────────┘
par └────┘ └─────────────────────────┘
pid ┴ └─────────────────────────┘
st └────────────────────────────────────
1589 [exact h, exact (irrefl_of r a h).elim], lex.cons⟩
id ┴ ┴ └───────┘ ┴ ┴ ┴ └──────┘
src ┴└────┘ └────┘ └───────┘┴ ┴ ┴ └────┘ └──────┘
typ ┴└────┘┴ └────┘ └───────┘┴┴┴┴┴┴└────┘ └──────┘
doc └────┘ └────┘ ┴ ┴ ┴ └────┘
txt └────┘ └────┘ ┴ ┴ ┴ └────┘
par └────┘ └────┘ ┴ ┴ ┴ └────┘
pid ┴ ┴ ┴ ┴ ┴ └───┘┴
st ────────────────────────────────────────┘
1590
1591 @[simp] theorem not_nil_right (r : α → α → Prop) (l : list α) : ¬ lex r l [].
id ┴ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ └┘
src └──┘ ┴ └─┘ └┘
typ ┴ ┴ └──┘ ┴ ┴ └─┘ ┴ ┴ └┘
doc └──┘
1592
1593 instance is_order_connected (r : α → α → Prop)
id ┴ ┴
typ ┴ ┴
1594 [is_order_connected α r] [is_trichotomous α r] :
id └────────────────┘ ┴ ┴ └─────────────┘ ┴ ┴
src └────────────────┘ └─────────────┘
typ └────────────────┘ ┴ ┴ └─────────────┘ ┴ ┴
doc └────────────────┘
1595 is_order_connected (list α) (lex r) :=
id └────────────────┘ └──┘ ┴ └─┘ ┴
src └────────────────┘ └──┘ └─┘
typ └────────────────┘ └──┘ ┴ └─┘ ┴
doc └────────────────┘
1596 ⟨λ l₁, match l₁ with
id └┘ └┘
typ └┘ └┘
1597 | _, [], c::l₃, nil := or.inr nil
id └┘ └┘ └─┘ └────┘ └─┘
src └┘ └┘ └─┘ └────┘ └─┘
typ └┘ └┘ └─┘ └────┘ └─┘
1598 | _, [], c::l₃, rel _ := or.inr nil
id └┘ └┘ └─┘ └────┘ └─┘
src └┘ └┘ └─┘ └────┘ └─┘
typ └┘ └┘ └─┘ └────┘ └─┘
1599 | _, [], c::l₃, cons _ := or.inr nil
id └┘ └┘ └──┘ └────┘ └─┘
src └┘ └┘ └──┘ └────┘ └─┘
typ └┘ └┘ └──┘ └────┘ └─┘
1600 | _, b::l₂, c::l₃, nil := or.inl nil
id └┘ └┘ └─┘ └────┘ └─┘
src └┘ └┘ └─┘ └────┘ └─┘
typ └┘ └┘ └─┘ └────┘ └─┘
1601 | a::l₁, b::l₂, c::l₃, rel h :=
id └┘ ┴└┘ └┘ └─┘ ┴
src └┘ └┘ └┘ └─┘
typ └┘ ┴└┘ └┘ └─┘ ┴
1602 (is_order_connected.conn _ b _ h).imp rel rel
id └─────────────────────┘ └─┘ └─┘ └─┘
src └─────────────────────┘ └─┘ └─┘ └─┘
typ └─────────────────────┘ └─┘ └─┘ └─┘
1603 | a::l₁, b::l₂, _::l₃, cons h := begin
id └┘ └┘ └┘ └──┘
src └┘ └┘ └┘ └──┘
typ └┘ └┘ └┘ └──┘
st └─────
1604 rcases trichotomous_of r a b with ab | rfl | ab,
id └─────────────┘ ┴ ┴ ┴
src └─────┘└─────────────┘┴ ┴ ┴ └─────────────────┘
typ └─────┘└─────────────┘┴┴┴┴┴┴└─────────────────┘
doc └─────┘ ┴ ┴ ┴ └─────────────────┘
txt └─────┘ ┴ ┴ ┴ └─────────────────┘
par └─────┘ ┴ ┴ ┴ └─────────────────┘
pid ┴ ┴ ┴ ┴ └─────────────────┘
st ──────────────────────────────────────────────────┘└─
1605 { exact or.inl (rel ab) },
id └────┘ └─┘ └┘
src └────┘└────┘┴ └─┘┴ └┘
typ └────┘└────┘┴ └─┘┴└┘└┘
doc └────┘ ┴ ┴ └┘
txt └────┘ ┴ ┴ └┘
par └────┘ ┴ ┴ └┘
pid ┴ ┴ ┴ ┴┴
st ─────┘└────────────────────┘└┘└
1606 { exact (_match _ l₂ _ h).imp cons cons },
id └────┘ └┘ ┴ └──┘
src └────┘ └─┘ └─┘ └────┘ ┴└──┘┴
typ └────┘ └────┘└─┘└┘└─┘┴└────┘ ┴└──┘┴
doc └────┘ └─┘ └─┘ └────┘ ┴ ┴
txt └────┘ └─┘ └─┘ └────┘ ┴ ┴
par └────┘ └─┘ └─┘ └────┘ ┴ ┴
pid ┴ └─┘ └─┘ └────┘ ┴ ┴
st ─────┘└────────────────────────────────────┘└┘└
1607 { exact or.inr (rel ab) }
id └────┘ └─┘ └┘
src └────┘└────┘┴ └─┘┴ └┘
typ └────┘└────┘┴ └─┘┴└┘└┘
doc └────┘ ┴ ┴ └┘
txt └────┘ ┴ ┴ └┘
par └────┘ ┴ ┴ └┘
pid ┴ ┴ ┴ ┴┴
st ───────────────────────────┘└─
1608 end
st ────┘
1609 end⟩
1610
1611 instance is_trichotomous (r : α → α → Prop) [is_trichotomous α r] :
id ┴ ┴ └─────────────┘ ┴ ┴
src └─────────────┘
typ ┴ ┴ └─────────────┘ ┴ ┴
1612 is_trichotomous (list α) (lex r) :=
id └─────────────┘ └──┘ ┴ └─┘ ┴
src └─────────────┘ └──┘ └─┘
typ └─────────────┘ └──┘ ┴ └─┘ ┴
1613 ⟨λ l₁, match l₁ with
id └┘ └┘
typ └┘ └┘
1614 | [], [] := or.inr (or.inl rfl)
id └┘ └┘ └────┘ └────┘ └─┘
src └┘ └┘ └────┘ └────┘ └─┘
typ └┘ └┘ └────┘ └────┘ └─┘
1615 | [], b::l₂ := or.inl nil
id └┘ └┘ └────┘ └─┘
src └┘ └┘ └────┘ └─┘
typ └┘ └┘ └────┘ └─┘
1616 | a::l₁, [] := or.inr (or.inr nil)
id └┘ └┘ └────┘ └────┘ └─┘
src └┘ └┘ └────┘ └────┘ └─┘
typ └┘ └┘ └────┘ └────┘ └─┘
1617 | a::l₁, b::l₂ := begin
id └┘ └┘
src └┘ └┘
typ └┘ └┘
st └─────
1618 rcases trichotomous_of r a b with ab | rfl | ab,
id └─────────────┘ ┴ ┴ ┴
src └─────┘└─────────────┘┴ ┴ ┴ └─────────────────┘
typ └─────┘└─────────────┘┴┴┴┴┴┴└─────────────────┘
doc └─────┘ ┴ ┴ ┴ └─────────────────┘
txt └─────┘ ┴ ┴ ┴ └─────────────────┘
par └─────┘ ┴ ┴ ┴ └─────────────────┘
pid ┴ ┴ ┴ ┴ └─────────────────┘
st ──────────────────────────────────────────────────┘└─
1619 { exact or.inl (rel ab) },
id └────┘ └─┘ └┘
src └────┘└────┘┴ └─┘┴ └┘
typ └────┘└────┘┴ └─┘┴└┘└┘
doc └────┘ ┴ ┴ └┘
txt └────┘ ┴ ┴ └┘
par └────┘ ┴ ┴ └┘
pid ┴ ┴ ┴ ┴┴
st ─────┘└────────────────────┘└┘└
1620 { exact (_match l₁ l₂).imp cons
id └────┘ └┘ └┘
src └────┘ ┴ ┴ └────┘ └
typ └────┘ └────┘┴└┘┴└┘└────┘ └
doc └────┘ ┴ ┴ └────┘ └
txt └────┘ ┴ ┴ └────┘ └
par └────┘ ┴ ┴ └────┘ └
pid ┴ ┴ ┴ └────┘ └
st ─────┘└─────────────────────────────
1621 (or.imp (congr_arg _) cons) },
id └────┘ └───────┘ └──┘
src ─────┘ └────┘┴ └───────┘└──┘└──┘└┘
typ ─────┘ └────┘┴ └───────┘└──┘└──┘└┘
doc ─────┘ ┴ └──┘ └┘
txt ─────┘ ┴ └──┘ └┘
par ─────┘ ┴ └──┘ └┘
pid ─────┘ ┴ └──┘ ┴┴
st ─────────────────────────────────┘└┘└
1622 { exact or.inr (or.inr (rel ab)) }
id └────┘ └─┘ └┘
src └────┘ ┴ └────┘┴ └─┘┴ └─┘
typ └────┘ ┴ └────┘┴ └─┘┴└┘└─┘
doc └────┘ ┴ ┴ ┴ └─┘
txt └────┘ ┴ ┴ ┴ └─┘
par └────┘ ┴ ┴ ┴ └─┘
pid ┴ ┴ ┴ ┴ └┘┴
st ────────────────────────────────────┘└─
1623 end
st ────┘
1624 end⟩
1625
1626 instance is_asymm (r : α → α → Prop)
id ┴ ┴
typ ┴ ┴
1627 [is_asymm α r] : is_asymm (list α) (lex r) :=
id └──────┘ ┴ ┴ └──────┘ └──┘ ┴ └─┘ ┴
src └──────┘ └──────┘ └──┘ └─┘
typ └──────┘ ┴ ┴ └──────┘ └──┘ ┴ └─┘ ┴
1628 ⟨λ l₁, match l₁ with
id └┘ └┘
typ └┘ └┘
1629 | a::l₁, b::l₂, lex.rel h₁, lex.rel h₂ := asymm h₁ h₂
id └┘ └┘ └┘ └─────┘ └┘ └───┘
src └┘ └┘ └─────┘ └───┘
typ └┘ └┘ └┘ └─────┘ └┘ └───┘
1630 | a::l₁, b::l₂, lex.rel h₁, lex.cons h₂ := asymm h₁ h₁
id └┘ └┘ └─────┘ └┘ └──────┘ └───┘
src └┘ └┘ └─────┘ └──────┘ └───┘
typ └┘ └┘ └─────┘ └┘ └──────┘ └───┘
1631 | a::l₁, b::l₂, lex.cons h₁, lex.rel h₂ := asymm h₂ h₂
id └┘ └┘ └──────┘ └─────┘ └┘ └───┘
src └┘ └┘ └──────┘ └─────┘ └───┘
typ └┘ └┘ └──────┘ └─────┘ └┘ └───┘
1632 | a::l₁, b::l₂, lex.cons h₁, lex.cons h₂ :=
id └┘ └┘ └──────┘
src └┘ └┘ └──────┘
typ └┘ └┘ └──────┘
1633 by exact _match _ _ h₁ h₂
id └────┘ └┘ └┘
src └────┘ └───┘ ┴ ┴
typ └────┘└────┘└───┘└┘┴└┘┴
doc └────┘ └───┘ ┴ ┴
txt └────┘ └───┘ ┴ ┴
par └────┘ └───┘ ┴ ┴
pid ┴ └───┘ ┴ ┴
st └──────────────────────┘
1634 end⟩
1635
1636 instance is_strict_total_order (r : α → α → Prop)
id ┴ ┴
typ ┴ ┴
1637 [is_strict_total_order' α r] : is_strict_total_order' (list α) (lex r) :=
id └────────────────────┘ ┴ ┴ └────────────────────┘ └──┘ ┴ └─┘ ┴
src └────────────────────┘ └────────────────────┘ └──┘ └─┘
typ └────────────────────┘ ┴ ┴ └────────────────────┘ └──┘ ┴ └─┘ ┴
doc └────────────────────┘ └────────────────────┘
1638 {..is_strict_weak_order_of_is_order_connected}
id └────────────────────────────────────────┘
src └────────────────────────────────────────┘
typ └────────────────────────────────────────┘
1639
1640 instance decidable_rel [decidable_eq α] (r : α → α → Prop)
id └──────────┘ ┴ ┴ ┴
src └──────────┘
typ └──────────┘ ┴ ┴ ┴
1641 [decidable_rel r] : decidable_rel (lex r)
id └───────────┘ ┴ └───────────┘ └─┘ ┴
src └───────────┘ └───────────┘ └─┘
typ └───────────┘ ┴ └───────────┘ └─┘ ┴
1642 | l₁ [] := is_false $ λ h, by cases h
id └┘ └──────┘ ┴ ┴
src └┘ └──────┘ └────┘ ┴
typ └┘ └──────┘ ┴ └────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st └───────┘
1643 | [] (b::l₂) := is_true lex.nil
id └┘ └┘ └─────┘ └─────┘
src └┘ └┘ └─────┘ └─────┘
typ └┘ └┘ └─────┘ └─────┘
1644 | (a::l₁) (b::l₂) := begin
id └┘ └┘
src └┘ └┘
typ └┘ └┘
st └─────
1645 haveI := decidable_rel l₁ l₂,
id └───────────┘ └┘ └┘
src └───────┘└───────────┘┴ ┴
typ └───────┘└───────────┘┴└┘┴└┘
doc └───────┘ ┴ ┴
txt └───────┘ ┴ ┴
par └───────┘ ┴ ┴
pid ┴└─┘ ┴ ┴
st ─────────────────────────────┘└─
1646 refine decidable_of_iff (r a b ∨ a = b ∧ lex r l₁ l₂) ⟨λ h, _, λ h, _⟩,
id └──────────────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └┘ └┘
src └─────┘└──────────────┘┴ ┴ ┴ ┴┴┴ ┴┴┴ ┴┴┴└─┘┴ ┴ ┴ └┘ └─────┘ └────┘
typ └─────┘└──────────────┘┴ ┴ ┴ ┴┴┴┴┴┴┴┴┴┴┴└─┘┴┴┴└┘┴└┘└┘ └─────┘ └────┘
doc └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └─────┘ └────┘
txt └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └─────┘ └────┘
par └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └─────┘ └────┘
pid ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └─────┘ └────┘
st ───────────────────────────────────────────────────────────────────────┘└─
1647 { rcases h with h | ⟨rfl, h⟩,
id ┴
src └─────┘ └────────────────┘
typ └─────┘┴└────────────────┘
doc └─────┘ └────────────────┘
txt └─────┘ └────────────────┘
par └─────┘ └────────────────┘
pid ┴ └────────────────┘
st ───┘└────────────────────────┘└─
1648 { exact lex.rel h },
id └─────┘ ┴
src └────┘└─────┘┴ ┴
typ └────┘└─────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ─────┘└──────────────┘└┘└
1649 { exact lex.cons h } },
id └──────┘ ┴
src └────┘└──────┘┴ ┴
typ └────┘└──────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ──────────────────────┘└──┘└
1650 { rcases h with _|⟨_,_,_,h⟩|⟨_,_,_,_,h⟩,
id ┴
src └─────┘ └───────────────────────────┘
typ └─────┘┴└───────────────────────────┘
doc └─────┘ └───────────────────────────┘
txt └─────┘ └───────────────────────────┘
par └─────┘ └───────────────────────────┘
pid ┴ └───────────────────────────┘
st ────────────────────────────────────────┘└─
1651 { exact or.inr ⟨rfl, h⟩ },
id └────┘ └─┘ ┴
src └────┘└────┘┴ └─┘└┘ └┘
typ └────┘└────┘┴ └─┘└┘┴└┘
doc └────┘ ┴ └┘ └┘
txt └────┘ ┴ └┘ └┘
par └────┘ ┴ └┘ └┘
pid ┴ ┴ └┘ ┴┴
st ─────┘└────────────────────┘└┘└
1652 { exact or.inl h } }
id └────┘ ┴
src └────┘└────┘┴ ┴
typ └────┘└────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ────────────────────┘└───
1653 end
st ──┘
1654
1655 theorem append_right (r : α → α → Prop) :
id ┴ ┴
typ ┴ ┴
1656 ∀ {s₁ s₂} t, lex r s₁ s₂ → lex r s₁ (s₂ ++ t)
id ┴└┘ └┘ ┴ └─┘ ┴ └┘ └┘ └─┘ ┴ └┘ └┘ └┘ ┴
src └─┘ └─┘ └┘
typ ┴└┘ └┘ ┴ └─┘ ┴ └┘ └┘ └─┘ ┴ └┘ └┘ └┘ ┴
1657 | _ _ t nil := nil
id └─┘ └─┘
src └─┘ └─┘
typ └─┘ └─┘
1658 | _ _ t (cons h) := cons (append_right _ h)
id └──┘ ┴ └──┘ └──────────┘
src └──┘ └──┘
typ └──┘ ┴ └──┘ └──────────┘
1659 | _ _ t (rel r) := rel r
id └─┘ ┴ └─┘
src └─┘ └─┘
typ └─┘ ┴ └─┘
1660
1661 theorem append_left (R : α → α → Prop) {t₁ t₂} (h : lex R t₁ t₂) :
id ┴ ┴ └─┘ ┴ └┘ └┘
src └─┘
typ ┴ ┴ └─┘ ┴ └┘ └┘
1662 ∀ s, lex R (s ++ t₁) (s ++ t₂)
id ┴ └─┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘
src └─┘ └┘ └┘
typ ┴ └─┘ ┴ ┴ └┘ └┘ ┴ └┘ └┘
1663 | [] := h
id └┘ ┴
src └┘
typ └┘ ┴
1664 | (a::l) := cons (append_left l)
id └┘┴ └──┘ └─────────┘
src └┘ └──┘
typ └┘┴ └──┘ └─────────┘
1665
1666 theorem imp {r s : α → α → Prop} (H : ∀ a b, r a b → s a b) :
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1667 ∀ l₁ l₂, lex r l₁ l₂ → lex s l₁ l₂
id └┘ └┘ └─┘ ┴ └┘ └┘ └─┘ ┴ └┘ └┘
src └─┘ └─┘
typ └┘ └┘ └─┘ ┴ └┘ └┘ └─┘ ┴ └┘ └┘
1668 | _ _ nil := nil
id └─┘ └─┘
src └─┘ └─┘
typ └─┘ └─┘
1669 | _ _ (cons h) := cons (imp _ _ h)
id └──┘ ┴ └──┘ └─┘
src └──┘ └──┘
typ └──┘ ┴ └──┘ └─┘
1670 | _ _ (rel r) := rel (H _ _ r)
id └─┘ ┴ └─┘ ┴
src └─┘ └─┘
typ └─┘ ┴ └─┘ ┴
1671
1672 theorem to_ne : ∀ {l₁ l₂ : list α}, lex (≠) l₁ l₂ → l₁ ≠ l₂
id ┴ └──┘ ┴ └─┘ ┴ └┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ ┴ ┴
typ ┴ └──┘ ┴ └─┘ ┴ └┘ └┘ └┘ ┴ └┘
1673 | _ _ (cons h) e := to_ne h (list.cons.inj e).2
id └──┘ ┴ ┴ └───┘ └───────────┘ ┴
src └──┘ └───────────┘ ┴
typ └──┘ ┴ ┴ └───┘ └───────────┘ ┴
1674 | _ _ (rel r) e := r (list.cons.inj e).1
id └─┘ ┴ ┴ └───────────┘ ┴
src └─┘ └───────────┘ ┴
typ └─┘ ┴ ┴ └───────────┘ ┴
1675
1676 theorem ne_iff {l₁ l₂ : list α} (H : length l₁ ≤ length l₂) :
id └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
src └──┘ └────┘ ┴ └────┘
typ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
1677 lex (≠) l₁ l₂ ↔ l₁ ≠ l₂ :=
id └─┘ ┴ └┘ └┘ ┴ └┘ ┴ └┘
src └─┘ ┴ ┴ ┴
typ └─┘ ┴ └┘ └┘ ┴ └┘ ┴ └┘
1678 ⟨to_ne, λ h, begin
id └───┘ ┴
src └───┘
typ └───┘ ┴
st └─────
1679 induction l₁ with a l₁ IH generalizing l₂; cases l₂ with b l₂,
id └┘ └┘
src └────────┘ └───────────────────────────┘ └────┘ └────────┘
typ └────────┘└┘└───────────────────────────┘ └────┘└┘└────────┘
doc └────────┘ └───────────────────────────┘ └────┘ └────────┘
txt └────────┘ └───────────────────────────┘ └────┘ └────────┘
par └────────┘ └───────────────────────────┘ └────┘ └────────┘
pid ┴ ┴└──────────┘└──────────────┘ ┴ └────────┘
st ──────────────────────────────────────────────────────────────┘└─
1680 { contradiction },
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid ┴
st ───┘└────────────┘└┘└
1681 { apply nil },
id └─┘
src └────┘└─┘┴
typ └────┘└─┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───┘└────────┘└┘└
1682 { exact (not_lt_of_ge H).elim (succ_pos _) },
id └──────────┘ ┴ └──────┘
src └────┘ └──────────┘┴ └─────┘ └──────┘└──┘
typ └────┘ └──────────┘┴┴└─────┘ └──────┘└──┘
doc └────┘ ┴ └─────┘ └──┘
txt └────┘ ┴ └─────┘ └──┘
par └────┘ ┴ └─────┘ └──┘
pid ┴ ┴ └─────┘ └─┘┴
st ───┘└───────────────────────────────────────┘└┘└
1683 { cases classical.em (a = b) with ab ab,
id └──────────┘ ┴ ┴ ┴
src └────┘└──────────┘┴ ┴┴┴ └──────────┘
typ └────┘└──────────┘┴ ┴┴┴┴┴└──────────┘
doc └────┘ ┴ ┴ ┴ └──────────┘
txt └────┘ ┴ ┴ ┴ └──────────┘
par └────┘ ┴ ┴ ┴ └──────────┘
pid ┴ ┴ ┴ ┴ ┴└─────────┘
st ────────────────────────────────────────┘└─
1684 { subst b, apply cons,
id ┴ └──┘
src └────┘ └────┘└──┘
typ └────┘┴ └────┘└──┘
doc └────┘ └────┘
txt └────┘ └────┘
par └────┘ └────┘
pid ┴ ┴
st ─────┘└─────┘└──────────┘└─
1685 exact IH (le_of_succ_le_succ H) (mt (congr_arg _) h) },
id └┘ └────────────────┘ ┴ └┘ └───────┘ ┴
src └────┘ ┴ └────────────────┘┴ └┘ └┘┴ └───────┘└──┘ └┘
typ └────┘└┘┴ └────────────────┘┴┴└┘ └┘┴ └───────┘└──┘┴└┘
doc └────┘ ┴ ┴ └┘ ┴ └──┘ └┘
txt └────┘ ┴ ┴ └┘ ┴ └──┘ └┘
par └────┘ ┴ ┴ └┘ ┴ └──┘ └┘
pid ┴ ┴ ┴ └┘ ┴ └──┘ ┴┴
st ──────────────────────────────────────────────────────────┘└┘└
1686 { exact rel ab } }
id └─┘ └┘
src └────┘└─┘┴ ┴
typ └────┘└─┘┴└┘┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ──────────────────┘└───
1687 end⟩
st ──┘
1688
1689 end lex
1690
1691 --Note: this overrides an instance in core lean
1692 instance has_lt' [has_lt α] : has_lt (list α) := ⟨lex (<)⟩
id └────┘ ┴ └────┘ └──┘ ┴ └─┘ ┴
src └────┘ └────┘ └──┘ └─┘ ┴
typ └────┘ ┴ └────┘ └──┘ ┴ └─┘ ┴
1693
1694 theorem nil_lt_cons [has_lt α] (a : α) (l : list α) : [] < a :: l :=
id └────┘ ┴ ┴ └──┘ ┴ └┘ ┴ ┴ └┘ ┴
src └────┘ └──┘ └┘ ┴ └┘
typ └────┘ ┴ ┴ └──┘ ┴ └┘ ┴ ┴ └┘ ┴
1695 lex.nil
id └─────┘
src └─────┘
typ └─────┘
1696
1697 instance [linear_order α] : linear_order (list α) :=
id └──────────┘ ┴ └──────────┘ └──┘ ┴
src └──────────┘ └──────────┘ └──┘
typ └──────────┘ ┴ └──────────┘ └──┘ ┴
1698 linear_order_of_STO' (lex (<))
id └──────────────────┘ └─┘ ┴
src └──────────────────┘ └─┘ ┴
typ └──────────────────┘ └─┘ ┴
doc └──────────────────┘
1699
1700 --Note: this overrides an instance in core lean
1701 instance has_le' [linear_order α] : has_le (list α) :=
id └──────────┘ ┴ └────┘ └──┘ ┴
src └──────────┘ └────┘ └──┘
typ └──────────┘ ┴ └────┘ └──┘ ┴
1702 preorder.to_has_le _
id └────────────────┘
src └────────────────┘
typ └────────────────┘
1703
1704 instance [decidable_linear_order α] : decidable_linear_order (list α) :=
id └────────────────────┘ ┴ └────────────────────┘ └──┘ ┴
src └────────────────────┘ └────────────────────┘ └──┘
typ └────────────────────┘ ┴ └────────────────────┘ └──┘ ┴
1705 decidable_linear_order_of_STO' (lex (<))
id └────────────────────────────┘ └─┘ ┴
src └────────────────────────────┘ └─┘ ┴
typ └────────────────────────────┘ └─┘ ┴
doc └────────────────────────────┘
1706
1707 /- all & any -/
1708
1709 @[simp] theorem all_nil (p : α → bool) : all [] p = tt := rfl
id ┴ └──┘ └─┘ └┘ ┴ ┴ └┘ └─┘
src └──┘ └─┘ └┘ ┴ └┘ └─┘
typ ┴ └──┘ └─┘ └┘ ┴ ┴ └┘ └─┘
doc └──┘
1710
1711 @[simp] theorem all_cons (p : α → bool) (a : α) (l : list α) : all (a::l) p = (p a && all l p) := rfl
id ┴ └──┘ ┴ └──┘ ┴ └─┘ ┴└┘┴ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └─┘
src └──┘ └──┘ └─┘ └┘ ┴ └┘ └─┘ └─┘
typ ┴ └──┘ ┴ └──┘ ┴ └─┘ ┴└┘┴ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └─┘
doc └──┘
1712
1713 theorem all_iff_forall {p : α → bool} {l : list α} : all l p ↔ ∀ a ∈ l, p a :=
id ┴ └──┘ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘ └─┘ ┴
typ ┴ └──┘ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1714 begin
st └─────
1715 induction l with a l ih,
id ┴
src └────────┘ └──────────┘
typ └────────┘┴└──────────┘
doc └────────┘ └──────────┘
txt └────────┘ └──────────┘
par └────────┘ └──────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─
1716 { exact iff_of_true rfl (forall_mem_nil _) },
id └─────────┘ └─┘ └────────────┘
src └────┘└─────────┘┴└─┘┴ └────────────┘└──┘
typ └────┘└─────────┘┴└─┘┴ └────────────┘└──┘
doc └────┘ ┴ ┴ └──┘
txt └────┘ ┴ ┴ └──┘
par └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴ └─┘┴
st ───┘└───────────────────────────────────────┘└┘└
1717 simp only [all_cons, band_coe_iff, ih, forall_mem_cons]
id └──────┘ └──────────┘ └┘ └─────────────┘
src └─────────┘└──────┘└┘└──────────┘└┘ └┘└─────────────┘└┘
typ └─────────┘└──────┘└┘└──────────┘└┘└┘└┘└─────────────┘└┘
doc └─────────┘ └┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴┴
st ─────────────────────────────────────────────────────────┘
1718 end
st └─┘
1719
1720 theorem all_iff_forall_prop {p : α → Prop} [decidable_pred p]
id ┴ └────────────┘ ┴
src └────────────┘
typ ┴ └────────────┘ ┴
1721 {l : list α} : all l (λ a, p a) ↔ ∀ a ∈ l, p a :=
id └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └─┘ ┴
typ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1722 by simp only [all_iff_forall, bool.of_to_bool_iff]
id └────────────┘ └─────────────────┘
src └─────────┘└────────────┘└┘└─────────────────┘└─
typ └─────────┘└────────────┘└┘└─────────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────────────────────────
1723
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1724 @[simp] theorem any_nil (p : α → bool) : any [] p = ff := rfl
id ┴ └──┘ └─┘ └┘ ┴ ┴ └┘ └─┘
src └──┘ └─┘ └┘ ┴ └┘ └─┘
typ ┴ └──┘ └─┘ └┘ ┴ ┴ └┘ └─┘
doc └──┘
1725
1726 @[simp] theorem any_cons (p : α → bool) (a : α) (l : list α) : any (a::l) p = (p a || any l p) := rfl
id ┴ └──┘ ┴ └──┘ ┴ └─┘ ┴└┘┴ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └─┘
src └──┘ └──┘ └─┘ └┘ ┴ └┘ └─┘ └─┘
typ ┴ └──┘ ┴ └──┘ ┴ └─┘ ┴└┘┴ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ └─┘
doc └──┘
1727
1728 theorem any_iff_exists {p : α → bool} {l : list α} : any l p ↔ ∃ a ∈ l, p a :=
id ┴ └──┘ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
src └──┘ └──┘ └─┘ ┴ ┴ ┴
typ ┴ └──┘ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
1729 begin
st └─────
1730 induction l with a l ih,
id ┴
src └────────┘ └──────────┘
typ └────────┘┴└──────────┘
doc └────────┘ └──────────┘
txt └────────┘ └──────────┘
par └────────┘ └──────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─
1731 { exact iff_of_false bool.not_ff (not_exists_mem_nil _) },
id └──────────┘ └─────────┘ └────────────────┘
src └────┘└──────────┘┴└─────────┘┴ └────────────────┘└──┘
typ └────┘└──────────┘┴└─────────┘┴ └────────────────┘└──┘
doc └────┘ ┴ ┴ └──┘
txt └────┘ ┴ ┴ └──┘
par └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴ └─┘┴
st ───┘└────────────────────────────────────────────────────┘└┘└
1732 simp only [any_cons, bor_coe_iff, ih, exists_mem_cons_iff]
id └──────┘ └─────────┘ └┘ └─────────────────┘
src └─────────┘└──────┘└┘└─────────┘└┘ └┘└─────────────────┘└┘
typ └─────────┘└──────┘└┘└─────────┘└┘└┘└┘└─────────────────┘└┘
doc └─────────┘ └┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴┴
st ────────────────────────────────────────────────────────────┘
1733 end
st └─┘
1734
1735 theorem any_iff_exists_prop {p : α → Prop} [decidable_pred p]
id ┴ └────────────┘ ┴
src └────────────┘
typ ┴ └────────────┘ ┴
1736 {l : list α} : any l (λ a, p a) ↔ ∃ a ∈ l, p a :=
id └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
src └──┘ └─┘ ┴ ┴ ┴
typ └──┘ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
1737 by simp [any_iff_exists]
id └────────────┘
src └────┘└────────────┘└─
typ └────┘└────────────┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └──────────────────────
1738
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1739 theorem any_of_mem {p : α → bool} {a : α} {l : list α} (h₁ : a ∈ l) (h₂ : p a) : any l p :=
id ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ └──┘ ┴ └─┘
typ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
1740 any_iff_exists.2 ⟨_, h₁, h₂⟩
id └────────────┘┴ └┘ └┘
src └────────────┘┴
typ └────────────┘┴ └┘ └┘
1741
1742 @[priority 500] instance decidable_forall_mem {p : α → Prop} [decidable_pred p] (l : list α) :
id ┴ └────────────┘ ┴ └──┘ ┴
src └────────────┘ └──┘
typ ┴ └────────────┘ ┴ └──┘ ┴
1743 decidable (∀ x ∈ l, p x) :=
id └───────┘ ┴ ┴ ┴ ┴
src └───────┘
typ └───────┘ ┴ ┴ ┴ ┴
1744 decidable_of_iff _ all_iff_forall_prop
id └──────────────┘ └─────────────────┘
src └──────────────┘ └─────────────────┘
typ └──────────────┘ └─────────────────┘
1745
1746 instance decidable_exists_mem {p : α → Prop} [decidable_pred p] (l : list α) :
id ┴ └────────────┘ ┴ └──┘ ┴
src └────────────┘ └──┘
typ ┴ └────────────┘ ┴ └──┘ ┴
1747 decidable (∃ x ∈ l, p x) :=
id └───────┘ ┴ ┴ ┴┴ ┴ ┴
src └───────┘ ┴ ┴
typ └───────┘ ┴ ┴ ┴┴ ┴ ┴
1748 decidable_of_iff _ any_iff_exists_prop
id └──────────────┘ └─────────────────┘
src └──────────────┘ └─────────────────┘
typ └──────────────┘ └─────────────────┘
1749
1750 /- map for partial functions -/
1751
1752 /-- Partial map. If `f : Π a, p a → β` is a partial function defined on
1753 `a : α` satisfying `p`, then `pmap f l h` is essentially the same as `map f l`
1754 but is defined only when all members of `l` satisfy `p`, using the proof
1755 to apply `f`. -/
1756 @[simp] def pmap {p : α → Prop} (f : Π a, p a → β) : Π l : list α, (∀ a ∈ l, p a) → list β
id ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1757 | [] H := []
id └┘ └┘
src └┘ └┘
typ └┘ └┘
1758 | (a::l) H := f a (forall_mem_cons.1 H).1 :: pmap l (forall_mem_cons.1 H).2
id ┴└┘┴ ┴ ┴ └─────────────┘┴ ┴ └┘ └──┘ └─────────────┘┴ ┴
src └┘ └─────────────┘┴ ┴ └┘ └─────────────┘┴ ┴
typ ┴└┘┴ ┴ ┴ └─────────────┘┴ ┴ └┘ └──┘ └─────────────┘┴ ┴
1759
1760 /-- "Attach" the proof that the elements of `l` are in `l` to produce a new list
1761 with the same elements but in the type `{x // x ∈ l}`. -/
1762 def attach (l : list α) : list {x // x ∈ l} := pmap subtype.mk l (λ a, id)
id └──┘ ┴ └──┘ ┴┴ ┴ ┴ ┴ └──┘ └────────┘ ┴ ┴ └┘
src └──┘ └──┘ ┴ ┴ └──┘ └────────┘ └┘
typ └──┘ ┴ └──┘ ┴┴ ┴ ┴ ┴ └──┘ └────────┘ ┴ ┴ └┘
doc └──┘
1763
1764 theorem pmap_eq_map (p : α → Prop) (f : α → β) (l : list α) (H) :
id ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ └──┘ ┴
1765 @pmap _ _ p (λ a _, f a) l H = map f l :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src └──┘ ┴ └─┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
doc └──┘
1766 by induction l; [refl, simp only [*, pmap, map]]; split; refl
id ┴ ┴ └──┘ └─┘
src └────────┘ ┴└──┘ └────────────┘└──┘└┘└─┘┴ └───┘ └────
typ └────────┘┴ ┴└──┘ └────────────┘└──┘└┘└─┘┴ └───┘ └────
doc └────────┘ └──┘ └────────────┘└──┘└┘ ┴ └───┘ └────
txt └────────┘ └──┘ └────────────┘ └┘ ┴ └───┘ └────
par └────────┘ └──┘ └────────────┘ └┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ └┘ ┴ └
st └───────────────────────────────────────────────────────────
1767
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1768 theorem pmap_congr {p q : α → Prop} {f : Π a, p a → β} {g : Π a, q a → β}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1769 (l : list α) {H₁ H₂} (h : ∀ a h₁ h₂, f a h₁ = g a h₂) :
id └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ ┴
typ └──┘ ┴ ┴ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
1770 pmap f l H₁ = pmap g l H₂ :=
id └──┘ ┴ ┴ └┘ ┴ └──┘ ┴ ┴ └┘
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ └┘ ┴ └──┘ ┴ ┴ └┘
doc └──┘ └──┘
1771 by induction l with _ _ ih; [refl, rw [pmap, pmap, h, ih]]
id ┴ ┴ └──┘ └──┘ ┴
src └────────┘ └──────────┘ ┴└──┘ └──┘└──┘└┘└──┘└┘ └┘ ┴
typ └────────┘┴└──────────┘ ┴└──┘ └──┘└──┘└┘└──┘└┘┴└┘└┘┴
doc └────────┘ └──────────┘ └──┘ └──┘└──┘└┘└──┘└┘ └┘ ┴
txt └────────┘ └──────────┘ └──┘ └──┘ └┘ └┘ └┘ ┴
par └────────┘ └──────────┘ └──┘ └──┘ └┘ └┘ └┘ ┴
pid ┴ ┴└─────────┘ └┘ └┘ └┘ └┘ ┴
st └───────────────────────────────────┘└──┘└────┘└─┘└──┘┴┴
1772
1773 theorem map_pmap {p : α → Prop} (g : β → γ) (f : Π a, p a → β)
id ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1774 (l H) : map g (pmap f l H) = pmap (λ a h, g (f a h)) l H :=
id └─┘ ┴ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └─┘ └──┘ ┴ └──┘
typ └─┘ ┴ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘
1775 by induction l; [refl, simp only [*, pmap, map]]; split; refl
id ┴ ┴ └──┘ └─┘
src └────────┘ ┴└──┘ └────────────┘└──┘└┘└─┘┴ └───┘ └────
typ └────────┘┴ ┴└──┘ └────────────┘└──┘└┘└─┘┴ └───┘ └────
doc └────────┘ └──┘ └────────────┘└──┘└┘ ┴ └───┘ └────
txt └────────┘ └──┘ └────────────┘ └┘ ┴ └───┘ └────
par └────────┘ └──┘ └────────────┘ └┘ ┴ └───┘ └────
pid ┴ ┴└──┘└───┘ └┘ ┴ └
st └───────────────────────────────────────────────────────────
1776
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1777 theorem pmap_eq_map_attach {p : α → Prop} (f : Π a, p a → β)
id ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴
1778 (l H) : pmap f l H = l.attach.map (λ x, f x.1 (H _ x.2)) :=
id └──┘ ┴ ┴ ┴ ┴ ┴└─────┘└──┘ ┴ ┴ ┴┴ ┴ ┴┴
src └──┘ ┴ └─────┘└──┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴└─────┘└──┘ ┴ ┴ ┴┴ ┴ ┴┴
doc └──┘ └─────┘
1779 by rw [attach, map_pmap]; exact pmap_congr l (λ a h₁ h₂, rfl)
id └────┘ └──────┘ └────────┘ ┴ └─┘
src └──┘└────┘└┘└──────┘┴ └────┘└────────┘┴ ┴ └────────┘└─┘└─
typ └──┘└────┘└┘└──────┘┴ └────┘└────────┘┴┴┴ └────────┘└─┘└─
doc └──┘└────┘└┘ ┴ └────┘ ┴ ┴ └────────┘ └─
txt └──┘ └┘ ┴ └────┘ ┴ ┴ └────────┘ └─
par └──┘ └┘ ┴ └────┘ ┴ ┴ └────────┘ └─
pid └┘ └┘ ┴ ┴ ┴ ┴ └────────┘ ┴└
st └─────────┘└────────┘┴└─────────────────────────────────────
1780
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1781 theorem attach_map_val (l : list α) : l.attach.map subtype.val = l :=
id └──┘ ┴ ┴└─────┘└──┘ └─────────┘ ┴ ┴
src └──┘ └─────┘└──┘ └─────────┘ ┴
typ └──┘ ┴ ┴└─────┘└──┘ └─────────┘ ┴ ┴
doc └─────┘
1782 by rw [attach, map_pmap]; exact (pmap_eq_map _ _ _ _).trans (map_id l)
id └────┘ └──────┘ └─────────┘ └────┘ ┴
src └──┘└────┘└┘└──────┘┴ └────┘ └─────────┘└──────────────┘ └────┘┴ └─
typ └──┘└────┘└┘└──────┘┴ └────┘ └─────────┘└──────────────┘ └────┘┴┴└─
doc └──┘└────┘└┘ ┴ └────┘ └──────────────┘ ┴ └─
txt └──┘ └┘ ┴ └────┘ └──────────────┘ ┴ └─
par └──┘ └┘ ┴ └────┘ └──────────────┘ ┴ └─
pid └┘ └┘ ┴ ┴ └──────────────┘ ┴ ┴└
st └─────────┘└────────┘┴└──────────────────────────────────────────────
1783
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1784 @[simp] theorem mem_attach (l : list α) : ∀ x, x ∈ l.attach | ⟨a, h⟩ :=
id └──┘ ┴ ┴ ┴ ┴ ┴└─────┘
src └──┘ ┴ └─────┘
typ └──┘ ┴ ┴ ┴ ┴ ┴└─────┘
doc └──┘ └─────┘
1785 by have := mem_map.1 (by rw [attach_map_val]; exact h);
id └─────┘ └────────────┘ ┴
src └──────┘└─────┘└─┘ ┴└──┘└────────────┘┴└┘└────┘ ┴
typ └──────┘└─────┘└─┘ ┴└──┘└────────────┘┴└┘└────┘┴┴
doc └──────┘ └─┘ ┴└──┘ ┴└┘└────┘ ┴
txt └──────┘ └─┘ ┴└──┘ ┴└┘└────┘ ┴
par └──────┘ └─┘ ┴└──┘ ┴└┘└────┘ ┴
pid └───┘└─┘ └─┘ └───┘ └───────┘ ┴
st └────────────────────┘└─────────────────┘┴└───────┘└──
1786 { rcases this with ⟨⟨_, _⟩, m, rfl⟩, exact m }
id └──┘ ┴
src └─────┘ └────────────────────┘ └────┘ ┴
typ └─────┘└──┘└────────────────────┘ └────┘┴┴
doc └─────┘ └────────────────────┘ └────┘ ┴
txt └─────┘ └────────────────────┘ └────┘ ┴
par └─────┘ └────────────────────┘ └────┘ ┴
pid ┴ └────────────────────┘ ┴ ┴
st ──┘└─────────────────────────────────┘└────────┘└┘
1787
1788 @[simp] theorem mem_pmap {p : α → Prop} {f : Π a, p a → β}
id ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴
doc └──┘
1789 {l H b} : b ∈ pmap f l H ↔ ∃ a (h : a ∈ l), f a (H a h) = b :=
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └──┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘
1790 by simp only [pmap_eq_map_attach, mem_map, mem_attach, true_and, subtype.exists]
id └────────────────┘ └─────┘ └────────┘ └──────┘ └────────────┘
src └─────────┘└────────────────┘└┘└─────┘└┘└────────┘└┘└──────┘└┘└────────────┘└─
typ └─────────┘└────────────────┘└┘└─────┘└┘└────────┘└┘└──────┘└┘└────────────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴└
st └──────────────────────────────────────────────────────────────────────────────
1791
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1792 @[simp] theorem length_pmap {p : α → Prop} {f : Π a, p a → β}
id ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴
doc └──┘
1793 {l H} : length (pmap f l H) = length l :=
id └────┘ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴
src └────┘ └──┘ ┴ └────┘
typ └────┘ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴
doc └──┘
1794 by induction l; [refl, simp only [*, pmap, length]]
id ┴ ┴ └──┘ └────┘
src └────────┘ ┴└──┘ └────────────┘└──┘└┘└────┘┴
typ └────────┘┴ ┴└──┘ └────────────┘└──┘└┘└────┘┴
doc └────────┘ └──┘ └────────────┘└──┘└┘ ┴
txt └────────┘ └──┘ └────────────┘ └┘ ┴
par └────────┘ └──┘ └────────────┘ └┘ ┴
pid ┴ ┴└──┘└───┘ └┘ ┴
st └───────────────────────────────────────────────┘
1795
1796 @[simp] lemma length_attach (L : list α) : L.attach.length = L.length := length_pmap
id └──┘ ┴ ┴└─────┘└─────┘ ┴ ┴└─────┘ └─────────┘
src └──┘ └─────┘└─────┘ ┴ └─────┘ └─────────┘
typ └──┘ ┴ ┴└─────┘└─────┘ ┴ ┴└─────┘ └─────────┘
doc └──┘ └─────┘
1797
1798 /- find -/
1799
1800 section find
1801 variables {p : α → Prop} [decidable_pred p] {l : list α} {a : α}
id └────────────┘ └──┘
src └────────────┘ └──┘
typ └────────────┘ └──┘
1802
1803 @[simp] theorem find_nil (p : α → Prop) [decidable_pred p] : find p [] = none :=
id ┴ └────────────┘ ┴ └──┘ ┴ └┘ ┴ └──┘
src └────────────┘ └──┘ └┘ ┴ └──┘
typ ┴ └────────────┘ ┴ └──┘ ┴ └┘ ┴ └──┘
doc └──┘ └──┘
1804 rfl
id └─┘
src └─┘
typ └─┘
1805
1806 @[simp] theorem find_cons_of_pos (l) (h : p a) : find p (a::l) = some a :=
id ┴ ┴ └──┘ ┴ ┴└┘┴ ┴ └──┘ ┴
src └──┘ └┘ ┴ └──┘
typ ┴ ┴ └──┘ ┴ ┴└┘┴ ┴ └──┘ ┴
doc └──┘ └──┘
1807 if_pos h
id └────┘ ┴
src └────┘
typ └────┘ ┴
1808
1809 @[simp] theorem find_cons_of_neg (l) (h : ¬ p a) : find p (a::l) = find p l :=
id ┴ ┴ ┴ └──┘ ┴ ┴└┘┴ ┴ └──┘ ┴ ┴
src ┴ └──┘ └┘ ┴ └──┘
typ ┴ ┴ ┴ └──┘ ┴ ┴└┘┴ ┴ └──┘ ┴ ┴
doc └──┘ └──┘ └──┘
1810 if_neg h
id └────┘ ┴
src └────┘
typ └────┘ ┴
1811
1812 @[simp] theorem find_eq_none : find p l = none ↔ ∀ x ∈ l, ¬ p x :=
id └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └──┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──┘
1813 begin
st └─────
1814 induction l with a l IH,
id ┴
src └────────┘ └──────────┘
typ └────────┘┴└──────────┘
doc └────────┘ └──────────┘
txt └────────┘ └──────────┘
par └────────┘ └──────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─
1815 { exact iff_of_true rfl (forall_mem_nil _) },
id └─────────┘ └─┘ └────────────┘
src └────┘└─────────┘┴└─┘┴ └────────────┘└──┘
typ └────┘└─────────┘┴└─┘┴ └────────────┘└──┘
doc └────┘ ┴ ┴ └──┘
txt └────┘ ┴ ┴ └──┘
par └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴ └─┘┴
st ───┘└───────────────────────────────────────┘└┘└
1816 rw forall_mem_cons, by_cases h : p a,
id └─────────────┘ ┴ ┴
src └─┘└─────────────┘ └───────┘ └─┘ ┴
typ └─┘└─────────────┘ └───────┘ └─┘┴┴┴
doc └─┘ └───────┘ └─┘ ┴
txt └─┘ └───────┘ └─┘ ┴
par └─┘ └───────┘ └─┘ ┴
pid ┴ ┴ └─┘ ┴
st ───────────────────┘└────────────────┘└─
1817 { simp only [find_cons_of_pos _ h, h, not_true, false_and] },
id └──────────────┘ ┴ ┴ └──────┘ └───────┘
src └─────────┘└──────────────┘└─┘ └┘ └┘└──────┘└┘└───────┘└┘
typ └─────────┘└──────────────┘└─┘┴└┘┴└┘└──────┘└┘└───────┘└┘
doc └─────────┘ └─┘ └┘ └┘ └┘ └┘
txt └─────────┘ └─┘ └┘ └┘ └┘ └┘
par └─────────┘ └─┘ └┘ └┘ └┘ └┘
pid ┴└──┘└┘ └─┘ └┘ └┘ └┘ ┴┴
st ───┘└───────────────────────────────────────────────────────┘└┘└
1818 { rwa [find_cons_of_neg _ h, iff_true_intro h, true_and] }
id └──────────────┘ ┴ └────────────┘ ┴ └──────┘
src └───┘└──────────────┘└─┘ └┘└────────────┘┴ └┘└──────┘└┘
typ └───┘└──────────────┘└─┘┴└┘└────────────┘┴┴└┘└──────┘└┘
doc └───┘ └─┘ └┘ ┴ └┘ └┘
txt └───┘ └─┘ └┘ ┴ └┘ └┘
par └───┘ └─┘ └┘ ┴ └┘ └┘
pid └┘ └─┘ └┘ ┴ └┘ ┴┴
st ────────────────────────────┘└────────────────┘└────────┘┴┴└─
1819 end
st ──┘
1820
1821 @[simp] theorem find_some (H : find p l = some a) : p a :=
id └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴
doc └──┘ └──┘
1822 begin
st └─────
1823 induction l with b l IH, {contradiction},
id ┴
src └────────┘ └──────────┘ └───────────┘
typ └────────┘┴└──────────┘ └───────────┘
doc └────────┘ └──────────┘ └───────────┘
txt └────────┘ └──────────┘ └───────────┘
par └────────┘ └──────────┘ └───────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└──────────────┘└┘└
1824 by_cases h : p b,
id ┴ ┴
src └───────┘ └─┘ ┴
typ └───────┘ └─┘┴┴┴
doc └───────┘ └─┘ ┴
txt └───────┘ └─┘ ┴
par └───────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ─────────────────┘└─
1825 { rw find_cons_of_pos _ h at H, cases H, exact h },
id └──────────────┘ ┴ ┴ ┴
src └─┘└──────────────┘└─┘ └───┘ └────┘ └────┘ ┴
typ └─┘└──────────────┘└─┘┴└───┘ └────┘┴ └────┘┴┴
doc └─┘ └─┘ └───┘ └────┘ └────┘ ┴
txt └─┘ └─┘ └───┘ └────┘ └────┘ ┴
par └─┘ └─┘ └───┘ └────┘ └────┘ ┴
pid ┴ └─┘ └───┘ ┴ ┴ ┴
st ───┘└──────────────────────────┘└───────┘└────────┘└┘└
1826 { rw find_cons_of_neg _ h at H, exact IH H }
id └──────────────┘ ┴ └┘ ┴
src └─┘└──────────────┘└─┘ └───┘ └────┘ ┴ ┴
typ └─┘└──────────────┘└─┘┴└───┘ └────┘└┘┴┴┴
doc └─┘ └─┘ └───┘ └────┘ ┴ ┴
txt └─┘ └─┘ └───┘ └────┘ ┴ ┴
par └─┘ └─┘ └───┘ └────┘ ┴ ┴
pid ┴ └─┘ └───┘ ┴ ┴ ┴
st ───────────────────────────────┘└───────────┘└─
1827 end
st ──┘
1828
1829 @[simp] theorem find_mem (H : find p l = some a) : a ∈ l :=
id └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └──┘ ┴
typ └──┘ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘ └──┘
1830 begin
st └─────
1831 induction l with b l IH, {contradiction},
id ┴
src └────────┘ └──────────┘ └───────────┘
typ └────────┘┴└──────────┘ └───────────┘
doc └────────┘ └──────────┘ └───────────┘
txt └────────┘ └──────────┘ └───────────┘
par └────────┘ └──────────┘ └───────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└──────────────┘└┘└
1832 by_cases h : p b,
id ┴ ┴
src └───────┘ └─┘ ┴
typ └───────┘ └─┘┴┴┴
doc └───────┘ └─┘ ┴
txt └───────┘ └─┘ ┴
par └───────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ─────────────────┘└─
1833 { rw find_cons_of_pos _ h at H, cases H, apply mem_cons_self },
id └──────────────┘ ┴ ┴ └───────────┘
src └─┘└──────────────┘└─┘ └───┘ └────┘ └────┘└───────────┘┴
typ └─┘└──────────────┘└─┘┴└───┘ └────┘┴ └────┘└───────────┘┴
doc └─┘ └─┘ └───┘ └────┘ └────┘ ┴
txt └─┘ └─┘ └───┘ └────┘ └────┘ ┴
par └─┘ └─┘ └───┘ └────┘ └────┘ ┴
pid ┴ └─┘ └───┘ ┴ ┴ ┴
st ───┘└──────────────────────────┘└───────┘└────────────────────┘└┘└
1834 { rw find_cons_of_neg _ h at H, exact mem_cons_of_mem _ (IH H) }
id └──────────────┘ ┴ └─────────────┘ └┘ ┴
src └─┘└──────────────┘└─┘ └───┘ └────┘└─────────────┘└─┘ ┴ └┘
typ └─┘└──────────────┘└─┘┴└───┘ └────┘└─────────────┘└─┘ └┘┴┴└┘
doc └─┘ └─┘ └───┘ └────┘ └─┘ ┴ └┘
txt └─┘ └─┘ └───┘ └────┘ └─┘ ┴ └┘
par └─┘ └─┘ └───┘ └────┘ └─┘ ┴ └┘
pid ┴ └─┘ └───┘ ┴ └─┘ ┴ ┴┴
st ───────────────────────────────┘└───────────────────────────────┘└─
1835 end
st ──┘
1836
1837 end find
1838
1839 /- lookmap -/
1840 section lookmap
1841 variables (f : α → option α)
id └────┘
src └────┘
typ └────┘
1842
1843 @[simp] theorem lookmap_nil : [].lookmap f = [] := rfl
id └┘└─────┘ ┴ ┴ └┘ └─┘
src └┘└─────┘ ┴ └┘ └─┘
typ └┘└─────┘ ┴ ┴ └┘ └─┘
doc └──┘ └─────┘
1844
1845 @[simp] theorem lookmap_cons_none {a : α} (l : list α) (h : f a = none) :
id ┴ └──┘ ┴ ┴ ┴ ┴ └──┘
src └──┘ ┴ └──┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └──┘
doc └──┘
1846 (a :: l).lookmap f = a :: l.lookmap f :=
id ┴ └┘ ┴ └─────┘ ┴ ┴ ┴ └┘ ┴└──────┘ ┴
src └┘ └─────┘ ┴ └┘ └──────┘
typ ┴ └┘ ┴ └─────┘ ┴ ┴ ┴ └┘ ┴└──────┘ ┴
doc └─────┘ └──────┘
1847 by simp [lookmap, h]
id └─────┘ ┴
src └────┘└─────┘└┘ └─
typ └────┘└─────┘└┘┴└─
doc └────┘└─────┘└┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid ┴┴ └┘ ┴└
st └──────────────────
1848
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1849 @[simp] theorem lookmap_cons_some {a b : α} (l : list α) (h : f a = some b) :
id ┴ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └──┘ ┴
doc └──┘
1850 (a :: l).lookmap f = b :: l :=
id ┴ └┘ ┴ └─────┘ ┴ ┴ ┴ └┘ ┴
src └┘ └─────┘ ┴ └┘
typ ┴ └┘ ┴ └─────┘ ┴ ┴ ┴ └┘ ┴
doc └─────┘
1851 by simp [lookmap, h]
id └─────┘ ┴
src └────┘└─────┘└┘ └─
typ └────┘└─────┘└┘┴└─
doc └────┘└─────┘└┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid ┴┴ └┘ ┴└
st └──────────────────
1852
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1853 theorem lookmap_some : ∀ l : list α, l.lookmap some = l
id ┴ └──┘ ┴ ┴└──────┘ └──┘ ┴ ┴
src └──┘ └──────┘ └──┘ ┴
typ ┴ └──┘ ┴ ┴└──────┘ └──┘ ┴ ┴
doc └──────┘
1854 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1855 | (a::l) := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1856
1857 theorem lookmap_none : ∀ l : list α, l.lookmap (λ _, none) = l
id ┴ └──┘ ┴ ┴└──────┘ ┴ └──┘ ┴ ┴
src └──┘ └──────┘ └──┘ ┴
typ ┴ └──┘ ┴ ┴└──────┘ ┴ └──┘ ┴ ┴
doc └──────┘
1858 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1859 | (a::l) := congr_arg (cons a) (lookmap_none l)
id ┴└┘┴ └───────┘ └──┘ └──────────┘
src └┘ └───────┘ └──┘
typ ┴└┘┴ └───────┘ └──┘ └──────────┘
1860
1861 theorem lookmap_congr {f g : α → option α} :
id ┴ └────┘ ┴
src └────┘
typ ┴ └────┘ ┴
1862 ∀ {l : list α}, (∀ a ∈ l, f a = g a) → l.lookmap f = l.lookmap g
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴└──────┘ ┴ ┴ ┴└──────┘ ┴
src └──┘ ┴ └──────┘ ┴ └──────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴└──────┘ ┴ ┴ ┴└──────┘ ┴
doc └──────┘ └──────┘
1863 | [] H := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1864 | (a::l) H := begin
id └┘
src └┘
typ └┘
st └─────
1865 cases forall_mem_cons.1 H with H₁ H₂,
id └─────────────┘ ┴
src └────┘└─────────────┘└─┘ └─────────┘
typ └────┘└─────────────┘└─┘┴└─────────┘
doc └────┘ └─┘ └─────────┘
txt └────┘ └─┘ └─────────┘
par └────┘ └─┘ └─────────┘
pid ┴ └─┘ └─────────┘
st ─────────────────────────────────────┘└─
1866 cases h : g a with b,
id ┴ ┴
src └────┘ └─┘ ┴ └─────┘
typ └────┘ └─┘┴┴┴└─────┘
doc └────┘ └─┘ ┴ └─────┘
txt └────┘ └─┘ ┴ └─────┘
par └────┘ └─┘ ┴ └─────┘
pid ┴ └─┘ ┴ └─────┘
st ─────────────────────┘└─
1867 { simp [h, H₁.trans h, lookmap_congr H₂] },
id ┴ └──────┘ ┴ └───────────┘ └┘
src └────┘ └┘└──────┘┴ └┘ ┴ └┘
typ └────┘┴└┘└──────┘┴┴└┘└───────────┘┴└┘└┘
doc └────┘ └┘ ┴ └┘ ┴ └┘
txt └────┘ └┘ ┴ └┘ ┴ └┘
par └────┘ └┘ ┴ └┘ ┴ └┘
pid ┴┴ └┘ ┴ └┘ ┴ ┴┴
st ───┘└─────────────────────────────────────┘└┘└
1868 { simp [lookmap_cons_some _ _ h, lookmap_cons_some _ _ (H₁.trans h)] }
id └───────────────┘ ┴ └───────────────┘ └──────┘ ┴
src └────┘└───────────────┘└───┘ └┘└───────────────┘└───┘ └──────┘┴ └─┘
typ └────┘└───────────────┘└───┘┴└┘└───────────────┘└───┘ └──────┘┴┴└─┘
doc └────┘ └───┘ └┘ └───┘ ┴ └─┘
txt └────┘ └───┘ └┘ └───┘ ┴ └─┘
par └────┘ └───┘ └┘ └───┘ ┴ └─┘
pid ┴┴ └───┘ └┘ └───┘ ┴ └┘┴
st ──────────────────────────────────────────────────────────────────────┘└─
1869 end
st ──┘
1870
1871 theorem lookmap_of_forall_not {l : list α} (H : ∀ a ∈ l, f a = none) : l.lookmap f = l :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴└──────┘ ┴ ┴ ┴
src └──┘ ┴ └──┘ └──────┘ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴└──────┘ ┴ ┴ ┴
doc └──────┘
1872 (lookmap_congr H).trans (lookmap_none l)
id └───────────┘ ┴ └───┘ └──────────┘ ┴
src └───────────┘ └───┘ └──────────┘
typ └───────────┘ ┴ └───┘ └──────────┘ ┴
1873
1874 theorem lookmap_map_eq (g : α → β) (h : ∀ a (b ∈ f a), g a = g b) :
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
1875 ∀ l : list α, map g (l.lookmap f) = map g l
id ┴ └──┘ ┴ └─┘ ┴ ┴└──────┘ ┴ ┴ └─┘ ┴ ┴
src └──┘ └─┘ └──────┘ ┴ └─┘
typ ┴ └──┘ ┴ └─┘ ┴ ┴└──────┘ ┴ ┴ └─┘ ┴ ┴
doc └──────┘
1876 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1877 | (a::l) := begin
id └┘
src └┘
typ └┘
st └─────
1878 cases h' : f a with b,
id ┴ ┴
src └────┘ └─┘ ┴ └─────┘
typ └────┘ └─┘┴┴┴└─────┘
doc └────┘ └─┘ ┴ └─────┘
txt └────┘ └─┘ ┴ └─────┘
par └────┘ └─┘ ┴ └─────┘
pid ┴ └─┘ ┴ └─────┘
st ──────────────────────┘└─
1879 { simp [h', lookmap_map_eq] },
id └┘ └────────────┘
src └────┘ └┘ └┘
typ └────┘└┘└┘└────────────┘└┘
doc └────┘ └┘ └┘
txt └────┘ └┘ └┘
par └────┘ └┘ └┘
pid ┴┴ └┘ ┴┴
st ───┘└────────────────────────┘└┘└
1880 { simp [lookmap_cons_some _ _ h', h _ _ h'] }
id └───────────────┘ └┘ ┴ └┘
src └────┘└───────────────┘└───┘ └┘ └───┘ └┘
typ └────┘└───────────────┘└───┘└┘└┘┴└───┘└┘└┘
doc └────┘ └───┘ └┘ └───┘ └┘
txt └────┘ └───┘ └┘ └───┘ └┘
par └────┘ └───┘ └┘ └───┘ └┘
pid ┴┴ └───┘ └┘ └───┘ ┴┴
st ─────────────────────────────────────────────┘└─
1881 end
st ──┘
1882
1883 theorem lookmap_id' (h : ∀ a (b ∈ f a), a = b) (l : list α) : l.lookmap f = l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴└──────┘ ┴ ┴ ┴
src ┴ └──┘ └──────┘ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ ┴└──────┘ ┴ ┴ ┴
doc └──────┘
1884 by rw [← map_id (l.lookmap f), lookmap_map_eq, map_id]; exact h
id └────┘ └───────┘ ┴ └────────────┘ └────┘ ┴
src └────┘└────┘┴ └───────┘┴ └─┘└────────────┘└┘└────┘┴ └────┘ └
typ └────┘└────┘┴ └───────┘┴┴└─┘└────────────┘└┘└────┘┴ └────┘┴└
doc └────┘ ┴ └───────┘┴ └─┘ └┘ ┴ └────┘ └
txt └────┘ ┴ ┴ └─┘ └┘ ┴ └────┘ └
par └────┘ ┴ ┴ └─┘ └┘ ┴ └────┘ └
pid └──┘ ┴ ┴ └─┘ └┘ ┴ ┴ └
st └─────────────────────────┘└──────────────┘└──────┘┴└─────────
1885
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1886 theorem length_lookmap (l : list α) : length (l.lookmap f) = length l :=
id └──┘ ┴ └────┘ ┴└──────┘ ┴ ┴ └────┘ ┴
src └──┘ └────┘ └──────┘ ┴ └────┘
typ └──┘ ┴ └────┘ ┴└──────┘ ┴ ┴ └────┘ ┴
doc └──────┘
1887 by rw [← length_map, lookmap_map_eq _ (λ _, ()), length_map]; simp
id └────────┘ └────────────┘ └┘ └────────┘
src └────┘└────────┘└┘└────────────┘└─┘ └──┘└┘└─┘└────────┘┴ └────
typ └────┘└────────┘└┘└────────────┘└─┘ └──┘└┘└─┘└────────┘┴ └────
doc └────┘ └┘ └─┘ └──┘ └─┘ ┴ └────
txt └────┘ └┘ └─┘ └──┘ └─┘ ┴ └────
par └────┘ └┘ └─┘ └──┘ └─┘ ┴ └────
pid └──┘ └┘ └─┘ └──┘ └─┘ ┴ └
st └───────────────┘└──────────────────────────┘└──────────┘┴└──────
1888
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1889 end lookmap
1890
1891 /- filter_map -/
1892
1893 @[simp] theorem filter_map_nil (f : α → option β) : filter_map f [] = [] := rfl
id ┴ └────┘ ┴ └────────┘ ┴ └┘ ┴ └┘ └─┘
src └────┘ └────────┘ └┘ ┴ └┘ └─┘
typ ┴ └────┘ ┴ └────────┘ ┴ └┘ ┴ └┘ └─┘
doc └──┘
1894
1895 @[simp] theorem filter_map_cons_none {f : α → option β} (a : α) (l : list α) (h : f a = none) :
id ┴ └────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └──┘
src └────┘ └──┘ ┴ └──┘
typ ┴ └────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ └──┘
doc └──┘
1896 filter_map f (a :: l) = filter_map f l :=
id └────────┘ ┴ ┴ └┘ ┴ ┴ └────────┘ ┴ ┴
src └────────┘ └┘ ┴ └────────┘
typ └────────┘ ┴ ┴ └┘ ┴ ┴ └────────┘ ┴ ┴
1897 by simp only [filter_map, h]
id └────────┘ ┴
src └─────────┘└────────┘└┘ └─
typ └─────────┘└────────┘└┘┴└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └──────────────────────────
1898
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1899 @[simp] theorem filter_map_cons_some (f : α → option β)
id ┴ └────┘ ┴
src └────┘
typ ┴ └────┘ ┴
doc └──┘
1900 (a : α) (l : list α) {b : β} (h : f a = some b) :
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
1901 filter_map f (a :: l) = b :: filter_map f l :=
id └────────┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘ └────────┘ ┴ ┴
src └────────┘ └┘ ┴ └┘ └────────┘
typ └────────┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘ └────────┘ ┴ ┴
1902 by simp only [filter_map, h]; split; refl
id └────────┘ ┴
src └─────────┘└────────┘└┘ ┴ └───┘ └────
typ └─────────┘└────────┘└┘┴┴ └───┘ └────
doc └─────────┘ └┘ ┴ └───┘ └────
txt └─────────┘ └┘ ┴ └───┘ └────
par └─────────┘ └┘ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ ┴ └
st └───────────────────────────────────────
1903
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1904 theorem filter_map_eq_map (f : α → β) : filter_map (some ∘ f) = map f :=
id ┴ ┴ └────────┘ └──┘ ┴ ┴ ┴ └─┘ ┴
src └────────┘ └──┘ ┴ ┴ └─┘
typ ┴ ┴ └────────┘ └──┘ ┴ ┴ ┴ └─┘ ┴
1905 begin
st └─────
1906 funext l,
src └──────┘
typ └──────┘
doc └──────┘
txt └──────┘
par └──────┘
pid └┘
st ─────────┘└─
1907 induction l with a l IH, {refl},
id ┴
src └────────┘ └──────────┘ └──┘
typ └────────┘┴└──────────┘ └──┘
doc └────────┘ └──────────┘ └──┘
txt └────────┘ └──────────┘ └──┘
par └────────┘ └──────────┘ └──┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─────┘└┘└
1908 simp only [filter_map_cons_some (some ∘ f) _ _ rfl, IH, map_cons], split; refl
id └──────────────────┘ └──┘ ┴ ┴ └─┘ └┘ └──────┘
src └─────────┘└──────────────────┘┴ └──┘┴┴┴ └────┘└─┘└┘ └┘└──────┘┴ └───┘ └───┘
typ └─────────┘└──────────────────┘┴ └──┘┴┴┴┴└────┘└─┘└┘└┘└┘└──────┘┴ └───┘ └───┘
doc └─────────┘ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ └───┘ └───┘
txt └─────────┘ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ └───┘ └───┘
par └─────────┘ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ └───┘ └───┘
pid ┴└──┘└┘ ┴ ┴ ┴ └────┘ └┘ └┘ ┴ ┴
st ──────────────────────────────────────────────────────────────────┘└────────────┘
1909 end
st └─┘
1910
1911 theorem filter_map_eq_filter (p : α → Prop) [decidable_pred p] :
id ┴ └────────────┘ ┴
src └────────────┘
typ ┴ └────────────┘ ┴
1912 filter_map (option.guard p) = filter p :=
id └────────┘ └──────────┘ ┴ ┴ └────┘ ┴
src └────────┘ └──────────┘ ┴ └────┘
typ └────────┘ └──────────┘ ┴ ┴ └────┘ ┴
doc └──────────┘
1913 begin
st └─────
1914 funext l,
src └──────┘
typ └──────┘
doc └──────┘
txt └──────┘
par └──────┘
pid └┘
st ─────────┘└─
1915 induction l with a l IH, {refl},
id ┴
src └────────┘ └──────────┘ └──┘
typ └────────┘┴└──────────┘ └──┘
doc └────────┘ └──────────┘ └──┘
txt └────────┘ └──────────┘ └──┘
par └────────┘ └──────────┘ └──┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─────┘└┘└
1916 by_cases pa : p a,
id ┴ ┴
src └───────┘ └─┘ ┴
typ └───────┘ └─┘┴┴┴
doc └───────┘ └─┘ ┴
txt └───────┘ └─┘ ┴
par └───────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ──────────────────┘└─
1917 { simp only [filter_map, option.guard, IH, if_pos pa, filter_cons_of_pos _ pa], split; refl },
id └────────┘ └──────────┘ └┘ └────┘ └┘ └────────────────┘ └┘
src └─────────┘└────────┘└┘└──────────┘└┘ └┘└────┘┴ └┘└────────────────┘└─┘ ┴ └───┘ └───┘
typ └─────────┘└────────┘└┘└──────────┘└┘└┘└┘└────┘┴└┘└┘└────────────────┘└─┘└┘┴ └───┘ └───┘
doc └─────────┘ └┘└──────────┘└┘ └┘ ┴ └┘ └─┘ ┴ └───┘ └───┘
txt └─────────┘ └┘ └┘ └┘ ┴ └┘ └─┘ ┴ └───┘ └───┘
par └─────────┘ └┘ └┘ └┘ ┴ └┘ └─┘ ┴ └───┘ └───┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ └┘ └─┘ ┴ ┴
st ───┘└──────────────────────────────────────────────────────────────────────────┘└────────────┘└┘└
1918 { simp only [filter_map, option.guard, IH, if_neg pa, filter_cons_of_neg _ pa] }
id └────────┘ └──────────┘ └┘ └────┘ └┘ └────────────────┘ └┘
src └─────────┘└────────┘└┘└──────────┘└┘ └┘└────┘┴ └┘└────────────────┘└─┘ └┘
typ └─────────┘└────────┘└┘└──────────┘└┘└┘└┘└────┘┴└┘└┘└────────────────┘└─┘└┘└┘
doc └─────────┘ └┘└──────────┘└┘ └┘ ┴ └┘ └─┘ └┘
txt └─────────┘ └┘ └┘ └┘ ┴ └┘ └─┘ └┘
par └─────────┘ └┘ └┘ └┘ ┴ └┘ └─┘ └┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ └┘ └─┘ ┴┴
st ────────────────────────────────────────────────────────────────────────────────┘└─
1919 end
st ──┘
1920
1921 theorem filter_map_filter_map (f : α → option β) (g : β → option γ) (l : list α) :
id ┴ └────┘ ┴ ┴ └────┘ ┴ └──┘ ┴
src └────┘ └────┘ └──┘
typ ┴ └────┘ ┴ ┴ └────┘ ┴ └──┘ ┴
1922 filter_map g (filter_map f l) = filter_map (λ x, (f x).bind g) l :=
id └────────┘ ┴ └────────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ └──┘ ┴ ┴
src └────────┘ └────────┘ ┴ └────────┘ └──┘
typ └────────┘ ┴ └────────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ └──┘ ┴ ┴
1923 begin
st └─────
1924 induction l with a l IH, {refl},
id ┴
src └────────┘ └──────────┘ └──┘
typ └────────┘┴└──────────┘ └──┘
doc └────────┘ └──────────┘ └──┘
txt └────────┘ └──────────┘ └──┘
par └────────┘ └──────────┘ └──┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─────┘└┘└
1925 cases h : f a with b,
id ┴ ┴
src └────┘ └─┘ ┴ └─────┘
typ └────┘ └─┘┴┴┴└─────┘
doc └────┘ └─┘ ┴ └─────┘
txt └────┘ └─┘ ┴ └─────┘
par └────┘ └─┘ ┴ └─────┘
pid ┴ └─┘ ┴ └─────┘
st ─────────────────────┘└─
1926 { rw [filter_map_cons_none _ _ h, filter_map_cons_none, IH],
id └──────────────────┘ ┴ └──────────────────┘ └┘
src └──┘└──────────────────┘└───┘ └┘└──────────────────┘└┘ ┴
typ └──┘└──────────────────┘└───┘┴└┘└──────────────────┘└┘└┘┴
doc └──┘ └───┘ └┘ └┘ ┴
txt └──┘ └───┘ └┘ └┘ ┴
par └──┘ └───┘ └┘ └┘ ┴
pid └┘ └───┘ └┘ └┘ ┴
st ───┘└────────────────────────────┘└────────────────────┘└──┘┴└─
1927 simp only [h, option.none_bind'] },
id ┴ └───────────────┘
src └─────────┘ └┘└───────────────┘└┘
typ └─────────┘┴└┘└───────────────┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st ────────────────────────────────────┘└┘└
1928 rw filter_map_cons_some _ _ _ h,
id └──────────────────┘ ┴
src └─┘└──────────────────┘└─────┘
typ └─┘└──────────────────┘└─────┘┴
doc └─┘ └─────┘
txt └─┘ └─────┘
par └─┘ └─────┘
pid ┴ └─────┘
st ────────────────────────────────┘└─
1929 cases h' : g b with c;
id ┴ ┴
src └────┘ └─┘ ┴ └─────┘
typ └────┘ └─┘┴┴┴└─────┘
doc └────┘ └─┘ ┴ └─────┘
txt └────┘ └─┘ ┴ └─────┘
par └────┘ └─┘ ┴ └─────┘
pid ┴ └─┘ ┴ └─────┘
st ─────────────────────────
1930 [ rw [filter_map_cons_none _ _ h', filter_map_cons_none, IH],
id ┴ └──────────────────┘ └┘ └──────────────────┘ └┘
src ┴ └──┘└──────────────────┘└───┘ └┘└──────────────────┘└┘ ┴
typ ┴ └──┘└──────────────────┘└───┘└┘└┘└──────────────────┘└┘└┘┴
doc └──┘ └───┘ └┘ └┘ ┴
txt └──┘ └───┘ └┘ └┘ ┴
par └──┘ └───┘ └┘ └┘ ┴
pid └┘ └───┘ └┘ └┘ ┴
st ───────┘└─────────────────────────┘└────────────────────┘└──┘┴└─
1931 rw [filter_map_cons_some _ _ _ h', filter_map_cons_some, IH] ];
id └──────────────────┘ └┘ └──────────────────┘ └┘
src └──┘└──────────────────┘└─────┘ └┘└──────────────────┘└┘ └┘
typ └──┘└──────────────────┘└─────┘└┘└┘└──────────────────┘└┘└┘└┘
doc └──┘ └─────┘ └┘ └┘ └┘
txt └──┘ └─────┘ └┘ └┘ └┘
par └──┘ └─────┘ └┘ └┘ └┘
pid └┘ └─────┘ └┘ └┘ ┴┴
st ───────┘└───────────────────────────┘└────────────────────┘└──┘┴└───
1932 simp only [h, h', option.some_bind']
id ┴ └┘ └───────────────┘
src └─────────┘ └┘ └┘└───────────────┘└┘
typ └─────────┘┴└┘└┘└┘└───────────────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st ──────────────────────────────────────┘
1933 end
st └─┘
1934
1935 theorem map_filter_map (f : α → option β) (g : β → γ) (l : list α) :
id ┴ └────┘ ┴ ┴ ┴ └──┘ ┴
src └────┘ └──┘
typ ┴ └────┘ ┴ ┴ ┴ └──┘ ┴
1936 map g (filter_map f l) = filter_map (λ x, (f x).map g) l :=
id └─┘ ┴ └────────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └─┘ └────────┘ ┴ └────────┘ └─┘
typ └─┘ ┴ └────────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ └─┘ ┴ ┴
1937 by rw [← filter_map_eq_map, filter_map_filter_map]; refl
id └───────────────┘ └───────────────────┘
src └────┘└───────────────┘└┘└───────────────────┘┴ └────
typ └────┘└───────────────┘└┘└───────────────────┘┴ └────
doc └────┘ └┘ ┴ └────
txt └────┘ └┘ ┴ └────
par └────┘ └┘ ┴ └────
pid └──┘ └┘ ┴ └
st └──────────────────────┘└─────────────────────┘┴└──────
1938
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1939 theorem filter_map_map (f : α → β) (g : β → option γ) (l : list α) :
id ┴ ┴ ┴ └────┘ ┴ └──┘ ┴
src └────┘ └──┘
typ ┴ ┴ ┴ └────┘ ┴ └──┘ ┴
1940 filter_map g (map f l) = filter_map (g ∘ f) l :=
id └────────┘ ┴ └─┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
src └────────┘ └─┘ ┴ └────────┘ ┴
typ └────────┘ ┴ └─┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴
1941 by rw [← filter_map_eq_map, filter_map_filter_map]; refl
id └───────────────┘ └───────────────────┘
src └────┘└───────────────┘└┘└───────────────────┘┴ └────
typ └────┘└───────────────┘└┘└───────────────────┘┴ └────
doc └────┘ └┘ ┴ └────
txt └────┘ └┘ ┴ └────
par └────┘ └┘ ┴ └────
pid └──┘ └┘ ┴ └
st └──────────────────────┘└─────────────────────┘┴└──────
1942
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1943 theorem filter_filter_map (f : α → option β) (p : β → Prop) [decidable_pred p] (l : list α) :
id ┴ └────┘ ┴ ┴ └────────────┘ ┴ └──┘ ┴
src └────┘ └────────────┘ └──┘
typ ┴ └────┘ ┴ ┴ └────────────┘ ┴ └──┘ ┴
1944 filter p (filter_map f l) = filter_map (λ x, (f x).filter p) l :=
id └────┘ ┴ └────────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ └────┘ ┴ ┴
src └────┘ └────────┘ ┴ └────────┘ └────┘
typ └────┘ ┴ └────────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ └────┘ ┴ ┴
doc └────┘
1945 by rw [← filter_map_eq_filter, filter_map_filter_map]; refl
id └──────────────────┘ └───────────────────┘
src └────┘└──────────────────┘└┘└───────────────────┘┴ └────
typ └────┘└──────────────────┘└┘└───────────────────┘┴ └────
doc └────┘ └┘ ┴ └────
txt └────┘ └┘ ┴ └────
par └────┘ └┘ ┴ └────
pid └──┘ └┘ ┴ └
st └─────────────────────────┘└─────────────────────┘┴└──────
1946
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1947 theorem filter_map_filter (p : α → Prop) [decidable_pred p] (f : α → option β) (l : list α) :
id ┴ └────────────┘ ┴ ┴ └────┘ ┴ └──┘ ┴
src └────────────┘ └────┘ └──┘
typ ┴ └────────────┘ ┴ ┴ └────┘ ┴ └──┘ ┴
1948 filter_map f (filter p l) = filter_map (λ x, if p x then f x else none) l :=
id └────────┘ ┴ └────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └────────┘ └────┘ ┴ └────────┘ └──┘
typ └────────┘ ┴ └────┘ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
1949 begin
st └─────
1950 rw [← filter_map_eq_filter, filter_map_filter_map], congr,
id └──────────────────┘ └───────────────────┘
src └────┘└──────────────────┘└┘└───────────────────┘┴ └───┘
typ └────┘└──────────────────┘└┘└───────────────────┘┴ └───┘
doc └────┘ └┘ ┴
txt └────┘ └┘ ┴ └───┘
par └────┘ └┘ ┴ └───┘
pid └──┘ └┘ ┴
st ───────────────────────────┘└─────────────────────┘└──────┘└─
1951 funext x,
src └──────┘
typ └──────┘
doc └──────┘
txt └──────┘
par └──────┘
pid └┘
st ─────────┘└─
1952 show (option.guard p x).bind f = ite (p x) (f x) none,
id └──────────┘ ┴ └─┘ ┴ ┴ ┴ └──┘
src └───┘ └──────────┘┴ ┴ └─────┘ ┴┴┴└─┘┴ ┴ └┘ ┴ └┘└──┘
typ └───┘ └──────────┘┴ ┴ └─────┘ ┴┴┴└─┘┴ ┴┴ └┘ ┴┴┴└┘└──┘
doc └───┘ └──────────┘┴ ┴ └─────┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘
txt └───┘ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘
par └───┘ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘
pid └───┘ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘
st ─────────────────────────────────────────────────────────
1953 by_cases h : p x,
id ┴ ┴
src └───────┘ └─┘ ┴
typ └───────┘ └─┘┴┴┴
doc └───────┘ └─┘ ┴
txt └───────┘ └─┘ ┴
par └───────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ─────────────────┘└─
1954 { simp only [option.guard, if_pos h, option.some_bind'] },
id └──────────┘ └────┘ ┴ └───────────────┘
src └─────────┘└──────────┘└┘└────┘┴ └┘└───────────────┘└┘
typ └─────────┘└──────────┘└┘└────┘┴┴└┘└───────────────┘└┘
doc └─────────┘└──────────┘└┘ ┴ └┘ └┘
txt └─────────┘ └┘ ┴ └┘ └┘
par └─────────┘ └┘ ┴ └┘ └┘
pid ┴└──┘└┘ └┘ ┴ └┘ ┴┴
st ───┘└────────────────────────────────────────────────────┘└┘└
1955 { simp only [option.guard, if_neg h, option.none_bind'] }
id └──────────┘ └────┘ ┴ └───────────────┘
src └─────────┘└──────────┘└┘└────┘┴ └┘└───────────────┘└┘
typ └─────────┘└──────────┘└┘└────┘┴┴└┘└───────────────┘└┘
doc └─────────┘└──────────┘└┘ ┴ └┘ └┘
txt └─────────┘ └┘ ┴ └┘ └┘
par └─────────┘ └┘ ┴ └┘ └┘
pid ┴└──┘└┘ └┘ ┴ └┘ ┴┴
st ─────────────────────────────────────────────────────────┘└─
1956 end
st ──┘
1957
1958 @[simp] theorem filter_map_some (l : list α) : filter_map some l = l :=
id └──┘ ┴ └────────┘ └──┘ ┴ ┴ ┴
src └──┘ └────────┘ └──┘ ┴
typ └──┘ ┴ └────────┘ └──┘ ┴ ┴ ┴
doc └──┘
1959 by rw filter_map_eq_map; apply map_id
id └───────────────┘ └────┘
src └─┘└───────────────┘ └────┘└────┘└
typ └─┘└───────────────┘ └────┘└────┘└
doc └─┘ └────┘ └
txt └─┘ └────┘ └
par └─┘ └────┘ └
pid ┴ ┴ └
st └───────────────────────────────────
1960
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1961 @[simp] theorem mem_filter_map (f : α → option β) (l : list α) {b : β} :
id ┴ └────┘ ┴ └──┘ ┴ ┴
src └────┘ └──┘
typ ┴ └────┘ ┴ └──┘ ┴ ┴
doc └──┘
1962 b ∈ filter_map f l ↔ ∃ a, a ∈ l ∧ f a = some b :=
id ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘
typ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
1963 begin
st └─────
1964 induction l with a l IH,
id ┴
src └────────┘ └──────────┘
typ └────────┘┴└──────────┘
doc └────────┘ └──────────┘
txt └────────┘ └──────────┘
par └────────┘ └──────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─
1965 { split, { intro H, cases H }, { rintro ⟨_, H, _⟩, cases H } },
id ┴ ┴
src └───┘ └─────┘ └────┘ ┴ └──────────────┘ └────┘ ┴
typ └───┘ └─────┘ └────┘┴┴ └──────────────┘ └────┘┴┴
doc └───┘ └─────┘ └────┘ ┴ └──────────────┘ └────┘ ┴
txt └───┘ └─────┘ └────┘ ┴ └──────────────┘ └────┘ ┴
par └───┘ └─────┘ └────┘ ┴ └──────────────┘ └────┘ ┴
pid └┘ ┴ ┴ └────────┘ ┴ ┴
st ───┘└───┘└──┘└─────┘└────────┘└┘└─────────────────┘└────────┘└──┘└
1966 cases h : f a with b',
id ┴ ┴
src └────┘ └─┘ ┴ └──────┘
typ └────┘ └─┘┴┴┴└──────┘
doc └────┘ └─┘ ┴ └──────┘
txt └────┘ └─┘ ┴ └──────┘
par └────┘ └─┘ ┴ └──────┘
pid ┴ └─┘ ┴ └──────┘
st ──────────────────────┘└─
1967 { have : f a ≠ some b, {rw h, intro, contradiction},
id ┴ ┴ ┴ └──┘ ┴ ┴
src └─────┘ ┴ ┴┴┴└──┘┴ └─┘ └───┘ └───────────┘
typ └─────┘┴┴┴┴┴┴└──┘┴┴ └─┘┴ └───┘ └───────────┘
doc └─────┘ ┴ ┴ ┴ ┴ └─┘ └───┘ └───────────┘
txt └─────┘ ┴ ┴ ┴ ┴ └─┘ └───┘ └───────────┘
par └─────┘ ┴ ┴ ┴ ┴ └─┘ └───┘ └───────────┘
pid └───┘└┘ ┴ ┴ ┴ ┴ ┴
st ───┘└─────────────────┘└────┘┴└─────┘└─────────────┘└┘└
1968 simp only [filter_map_cons_none _ _ h, IH, mem_cons_iff,
id └──────────────────┘ ┴ └┘ └──────────┘
src └─────────┘└──────────────────┘└───┘ └┘ └┘└──────────┘└─
typ └─────────┘└──────────────────┘└───┘┴└┘└┘└┘└──────────┘└─
doc └─────────┘ └───┘ └┘ └┘ └─
txt └─────────┘ └───┘ └┘ └┘ └─
par └─────────┘ └───┘ └┘ └┘ └─
pid ┴└──┘└┘ └───┘ └┘ └┘ └─
st ─────────────────────────────────────────────────────────────
1969 or_and_distrib_right, exists_or_distrib, exists_eq_left, this, false_or] },
id └──────────────────┘ └───────────────┘ └────────────┘ └──┘ └──────┘
src ─────┘└──────────────────┘└┘└───────────────┘└┘└────────────┘└┘ └┘└──────┘└┘
typ ─────┘└──────────────────┘└┘└───────────────┘└┘└────────────┘└┘└──┘└┘└──────┘└┘
doc ─────┘ └┘ └┘ └┘ └┘ └┘
txt ─────┘ └┘ └┘ └┘ └┘ └┘
par ─────┘ └┘ └┘ └┘ └┘ └┘
pid ─────┘ └┘ └┘ └┘ └┘ ┴┴
st ──────────────────────────────────────────────────────────────────────────────┘└┘└
1970 { have : f a = some b ↔ b = b',
id ┴ ┴ └──┘ ┴ └┘
src └─────┘ ┴ ┴ ┴└──┘┴ ┴ ┴ ┴ ┴
typ └─────┘┴┴┴┴ ┴└──┘┴ ┴ ┴┴┴ ┴└┘
doc └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
txt └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
par └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
pid └───┘└┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
st ───────────────────────────────┘└─
1971 { split; intro t, {rw t at h; injection h}, {exact t.symm ▸ h} },
id ┴ ┴ └────┘ ┴ ┴
src └───┘ └─────┘ └─┘ └───┘ └────────┘ └────┘└────┘┴┴┴
typ └───┘ └─────┘ └─┘┴└───┘ └────────┘┴ └────┘└────┘┴┴┴┴
doc └───┘ └─────┘ └─┘ └───┘ └────────┘ └────┘ ┴ ┴
txt └───┘ └─────┘ └─┘ └───┘ └────────┘ └────┘ ┴ ┴
par └───┘ └─────┘ └─┘ └───┘ └────────┘ └────┘ ┴ ┴
pid └┘ ┴ └───┘ ┴ ┴ ┴ ┴
st ─────┘└────────────┘└────┘┴└────────────────┘└┘└────────────────┘└──┘└
1972 simp only [filter_map_cons_some _ _ _ h, IH, mem_cons_iff,
id └──────────────────┘ ┴ └┘ └──────────┘
src └─────────┘└──────────────────┘└─────┘ └┘ └┘└──────────┘└─
typ └─────────┘└──────────────────┘└─────┘┴└┘└┘└┘└──────────┘└─
doc └─────────┘ └─────┘ └┘ └┘ └─
txt └─────────┘ └─────┘ └┘ └┘ └─
par └─────────┘ └─────┘ └┘ └┘ └─
pid ┴└──┘└┘ └─────┘ └┘ └┘ └─
st ─────────────────────────────────────────────────────────────────
1973 or_and_distrib_right, exists_or_distrib, this, exists_eq_left] }
id └──────────────────┘ └───────────────┘ └──┘ └────────────┘
src ───────┘└──────────────────┘└┘└───────────────┘└┘ └┘└────────────┘└┘
typ ───────┘└──────────────────┘└┘└───────────────┘└┘└──┘└┘└────────────┘└┘
doc ───────┘ └┘ └┘ └┘ └┘
txt ───────┘ └┘ └┘ └┘ └┘
par ───────┘ └┘ └┘ └┘ └┘
pid ───────┘ └┘ └┘ └┘ ┴┴
st ──────────────────────────────────────────────────────────────────────┘└─
1974 end
st ──┘
1975
1976 theorem map_filter_map_of_inv (f : α → option β) (g : β → α)
id ┴ └────┘ ┴ ┴ ┴
src └────┘
typ ┴ └────┘ ┴ ┴ ┴
1977 (H : ∀ x : α, (f x).map g = some x) (l : list α) :
id ┴ ┴ ┴ └─┘ ┴ ┴ └──┘ ┴ └──┘ ┴
src └─┘ ┴ └──┘ └──┘
typ ┴ ┴ ┴ └─┘ ┴ ┴ └──┘ ┴ └──┘ ┴
1978 map g (filter_map f l) = l :=
id └─┘ ┴ └────────┘ ┴ ┴ ┴ ┴
src └─┘ └────────┘ ┴
typ └─┘ ┴ └────────┘ ┴ ┴ ┴ ┴
1979 by simp only [map_filter_map, H, filter_map_some]
id └────────────┘ ┴ └─────────────┘
src └─────────┘└────────────┘└┘ └┘└─────────────┘└─
typ └─────────┘└────────────┘└┘┴└┘└─────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────
1980
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1981 theorem filter_map_sublist_filter_map (f : α → option β) {l₁ l₂ : list α}
id ┴ └────┘ ┴ └──┘ ┴
src └────┘ └──┘
typ ┴ └────┘ ┴ └──┘ ┴
1982 (s : l₁ <+ l₂) : filter_map f l₁ <+ filter_map f l₂ :=
id └┘ └┘ └┘ └────────┘ ┴ └┘ └┘ └────────┘ ┴ └┘
src └┘ └────────┘ └┘ └────────┘
typ └┘ └┘ └┘ └────────┘ ┴ └┘ └┘ └────────┘ ┴ └┘
1983 by induction s with l₁ l₂ a s IH l₁ l₂ a s IH;
id ┴
src └────────┘ └─────────────────────────────┘
typ └────────┘┴└─────────────────────────────┘
doc └────────┘ └─────────────────────────────┘
txt └────────┘ └─────────────────────────────┘
par └────────┘ └─────────────────────────────┘
pid ┴ ┴└────────────────────────────┘
st └────────────────────────────────────────────
1984 simp only [filter_map]; cases f a with b;
id └────────┘ ┴ ┴
src └─────────┘└────────┘┴ └────┘ ┴ └─────┘
typ └─────────┘└────────┘┴ └────┘┴┴┴└─────┘
doc └─────────┘ ┴ └────┘ ┴ └─────┘
txt └─────────┘ ┴ └────┘ ┴ └─────┘
par └─────────┘ ┴ └────┘ ┴ └─────┘
pid ┴└──┘└┘ ┴ ┴ ┴ └─────┘
st ─────────────────────────────────────────────
1985 simp only [filter_map, IH, sublist.cons, sublist.cons2]
id └────────┘ └┘ └──────────┘ └───────────┘
src └─────────┘└────────┘└┘ └┘└──────────┘└┘└───────────┘└─
typ └─────────┘└────────┘└┘└┘└┘└──────────┘└┘└───────────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st ───────────────────────────────────────────────────────────
1986
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1987 theorem map_sublist_map (f : α → β) {l₁ l₂ : list α}
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
1988 (s : l₁ <+ l₂) : map f l₁ <+ map f l₂ :=
id └┘ └┘ └┘ └─┘ ┴ └┘ └┘ └─┘ ┴ └┘
src └┘ └─┘ └┘ └─┘
typ └┘ └┘ └┘ └─┘ ┴ └┘ └┘ └─┘ ┴ └┘
1989 by rw ← filter_map_eq_map; exact filter_map_sublist_filter_map _ s
id └───────────────┘ └───────────────────────────┘ ┴
src └───┘└───────────────┘ └────┘└───────────────────────────┘└─┘ └
typ └───┘└───────────────┘ └────┘└───────────────────────────┘└─┘┴└
doc └───┘ └────┘ └─┘ └
txt └───┘ └────┘ └─┘ └
par └───┘ └────┘ └─┘ └
pid └─┘ ┴ └─┘ └
st └────────────────────────────────────────────────────────────────
1990
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
1991 /- filter -/
src ─────────────
typ ─────────────
doc ─────────────
txt ─────────────
par ─────────────
pid ─────────────
st ─────────────
1992
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
1993 section filter
1994 variables {p : α → Prop} [decidable_pred p]
id └────────────┘
src └────────────┘
typ └────────────┘
1995
1996 lemma filter_congr {p q : α → Prop} [decidable_pred p] [decidable_pred q]
id ┴ └────────────┘ ┴ └────────────┘ ┴
src └────────────┘ └────────────┘
typ ┴ └────────────┘ ┴ └────────────┘ ┴
1997 : ∀ {l : list α}, (∀ x ∈ l, p x ↔ q x) → filter p l = filter q l
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
src └──┘ ┴ └────┘ ┴ └────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
1998 | [] _ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
1999 | (a::l) h := by rw forall_mem_cons at h; by_cases pa : p a;
id └┘ └─────────────┘ ┴ ┴
src └┘ └─┘└─────────────┘└───┘ └───────┘ └─┘ ┴
typ └┘ └─┘└─────────────┘└───┘ └───────┘ └─┘┴┴┴
doc └─┘ └───┘ └───────┘ └─┘ ┴
txt └─┘ └───┘ └───────┘ └─┘ ┴
par └─┘ └───┘ └───────┘ └─┘ ┴
pid ┴ └───┘ ┴ └─┘ ┴
st └────────────────────────────────────────────
2000 [simp only [filter_cons_of_pos _ pa, filter_cons_of_pos _ (h.1.1 pa), filter_congr h.2],
id ┴ └────────────────┘ └┘ └────────────────┘ ┴ └┘ └──────────┘ ┴
src ┴└─────────┘└────────────────┘└─┘ └┘└────────────────┘└─┘ └───┘ └─┘ ┴ └─┘
typ ┴└─────────┘└────────────────┘└─┘└┘└┘└────────────────┘└─┘ ┴└───┘└┘└─┘└──────────┘┴┴└─┘
doc └─────────┘ └─┘ └┘ └─┘ └───┘ └─┘ ┴ └─┘
txt └─────────┘ └─┘ └┘ └─┘ └───┘ └─┘ ┴ └─┘
par └─────────┘ └─┘ └┘ └─┘ └───┘ └─┘ ┴ └─┘
pid ┴└──┘└┘ └─┘ └┘ └─┘ └───┘ └─┘ ┴ └─┘
st ───────────────────────────────────────────────────────────────────────────────────────────
2001 simp only [filter_cons_of_neg _ pa, filter_cons_of_neg _ (mt h.1.2 pa), filter_congr h.2]]; split; refl
id └────────────────┘ └┘ └────────────────┘ └┘ ┴ └┘ └──────────┘ ┴
src └─────────┘└────────────────┘└─┘ └┘└────────────────┘└─┘ └┘┴ └───┘ └─┘ ┴ └─┘ └───┘ └────
typ └─────────┘└────────────────┘└─┘└┘└┘└────────────────┘└─┘ └┘┴┴└───┘└┘└─┘└──────────┘┴┴└─┘ └───┘ └────
doc └─────────┘ └─┘ └┘ └─┘ ┴ └───┘ └─┘ ┴ └─┘ └───┘ └────
txt └─────────┘ └─┘ └┘ └─┘ ┴ └───┘ └─┘ ┴ └─┘ └───┘ └────
par └─────────┘ └─┘ └┘ └─┘ ┴ └───┘ └─┘ ┴ └─┘ └───┘ └────
pid ┴└──┘└┘ └─┘ └┘ └─┘ ┴ └───┘ └─┘ ┴ └─┘ └
st ───────────────────────────────────────────────────────────────────────────────────────────────────────────
2002
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2003 @[simp] theorem filter_subset (l : list α) : filter p l ⊆ l :=
id └──┘ ┴ └────┘ ┴ ┴ ┴ ┴
src └──┘ └────┘ ┴
typ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴
doc └──┘
2004 subset_of_sublist $ filter_sublist l
id └───────────────┘ └────────────┘ ┴
src └───────────────┘ └────────────┘
typ └───────────────┘ └────────────┘ ┴
2005
2006 theorem of_mem_filter {a : α} : ∀ {l}, a ∈ filter p l → p a
id ┴ ┴┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
src ┴ └────┘
typ ┴ ┴┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
2007 | (b::l) ain :=
id ┴└┘┴
src └┘
typ ┴└┘┴
2008 if pb : p b then
id └┘ ┴
src └┘
typ └┘ ┴
2009 have a ∈ b :: filter p l, by simpa only [filter_cons_of_pos _ pb] using ain,
id ┴ ┴ └┘ └────┘ ┴ └────────────────┘ └┘ └─┘
src ┴ └┘ └────┘ └──────────┘└────────────────┘└─┘ └──────┘
typ ┴ ┴ └┘ └────┘ ┴ └──────────┘└────────────────┘└─┘└┘└──────┘└─┘
doc └──────────┘ └─┘ └──────┘
txt └──────────┘ └─┘ └──────┘
par └──────────┘ └─┘ └──────┘
pid ┴└──┘└┘ └─┘ ┴┴└────┘
st └─────────────────────────────────────────────┘
2010 or.elim (eq_or_mem_of_mem_cons this)
id └─────┘ └───────────────────┘ └──┘
src └─────┘ └───────────────────┘
typ └─────┘ └───────────────────┘ └──┘
2011 (assume : a = b, begin rw [← this] at pb, exact pb end)
id ┴ ┴ └──┘ └┘
src ┴ └────┘ └─────┘ └────┘ ┴
typ ┴ ┴ └────┘└──┘└─────┘ └────┘└┘┴
doc └────┘ └─────┘ └────┘ ┴
txt └────┘ └─────┘ └────┘ ┴
par └────┘ └─────┘ └────┘ ┴
pid └──┘ ┴└────┘ ┴ ┴
st └──────────────┘┴└────┘└─────────┘└─┘
2012 (assume : a ∈ filter p l, of_mem_filter this)
id ┴ ┴ └────┘ ┴ └───────────┘ └──┘
src ┴ └────┘
typ ┴ ┴ └────┘ ┴ └───────────┘ └──┘
2013 else
2014 begin simp only [filter_cons_of_neg _ pb] at ain, exact (of_mem_filter ain) end
id └────────────────┘ └┘ └───────────┘ └─┘ └─┘
src └─────────┘└────────────────┘└─┘ └──────┘ └────┘ ┴ └┘
typ └─────────┘└────────────────┘└─┘└┘└──────┘ └────┘ └───────────┘┴└─┘└┘└─┘
doc └─────────┘ └─┘ └──────┘ └────┘ ┴ └┘
txt └─────────┘ └─┘ └──────┘ └────┘ ┴ └┘
par └─────────┘ └─┘ └──────┘ └────┘ ┴ └┘
pid ┴└──┘└┘ └─┘ ┴┴└────┘ ┴ ┴ ┴┴
st └──────────────────────────────────────────────┘└──────────────────────────┘└─┘
2015
2016 theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
id ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ ┴
typ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
2017 filter_subset l h
id └───────────┘ ┴ ┴
src └───────────┘
typ └───────────┘ ┴ ┴
2018
2019 theorem mem_filter_of_mem {a : α} : ∀ {l}, a ∈ l → p a → a ∈ filter p l
id ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴
src ┴ ┴ └────┘
typ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴
2020 | (_::l) (or.inl rfl) pa := by rw filter_cons_of_pos _ pa; apply mem_cons_self
id └┘ └────┘ └─┘ └────────────────┘ └┘ └───────────┘
src └┘ └────┘ └─┘ └─┘└────────────────┘└─┘ └────┘└───────────┘┴
typ └┘ └────┘ └─┘ └─┘└────────────────┘└─┘└┘ └────┘└───────────┘┴
doc └─┘ └─┘ └────┘ ┴
txt └─┘ └─┘ └────┘ ┴
par └─┘ └─┘ └────┘ ┴
pid ┴ └─┘ ┴ ┴
st └───────────────────────────────────────────────┘
2021 | (b::l) (or.inr ain) pa := if pb : p b
id ┴└┘ └────┘ └┘ ┴
src └┘ └────┘ └┘
typ ┴└┘ └────┘ └┘ ┴
2022 then by rw [filter_cons_of_pos _ pb]; apply mem_cons_of_mem; apply mem_filter_of_mem ain pa
id └────────────────┘ └┘ └─────────────┘ └───────────────┘ └─┘ └┘
src └──┘└────────────────┘└─┘ ┴ └────┘└─────────────┘ └────┘ ┴ ┴ └
typ └──┘└────────────────┘└─┘└┘┴ └────┘└─────────────┘ └────┘└───────────────┘┴└─┘┴└┘└
doc └──┘ └─┘ ┴ └────┘ └────┘ ┴ ┴ └
txt └──┘ └─┘ ┴ └────┘ └────┘ ┴ ┴ └
par └──┘ └─┘ ┴ └────┘ └────┘ ┴ ┴ └
pid └┘ └─┘ ┴ ┴ ┴ ┴ ┴ └
st └──────────────────────────┘┴└───────────────────────────────────────────────────────
2023 else by rw [filter_cons_of_neg _ pb]; apply mem_filter_of_mem ain pa
id └────────────────┘ └┘ └───────────────┘ └─┘ └┘
src ───┘ └──┘└────────────────┘└─┘ ┴ └────┘ ┴ ┴ └
typ ───┘ └──┘└────────────────┘└─┘└┘┴ └────┘└───────────────┘┴└─┘┴└┘└
doc ───┘ └──┘ └─┘ ┴ └────┘ ┴ ┴ └
txt ───┘ └──┘ └─┘ ┴ └────┘ ┴ ┴ └
par ───┘ └──┘ └─┘ ┴ └────┘ ┴ ┴ └
pid ───┘ └┘ └─┘ ┴ ┴ ┴ ┴ └
st ───┘ └──────────────────────────┘┴└────────────────────────────────
2024
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2025 @[simp] theorem mem_filter {a : α} {l} : a ∈ filter p l ↔ a ∈ l ∧ p a :=
id ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ ┴ ┴ ┴
typ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘
2026 ⟨λ h, ⟨mem_of_mem_filter h, of_mem_filter h⟩, λ ⟨h₁, h₂⟩, mem_filter_of_mem h₁ h₂⟩
id ┴ └───────────────┘ ┴ └───────────┘ ┴ ┴└┘ └┘ └───────────────┘
src └───────────────┘ └───────────┘ └───────────────┘
typ ┴ └───────────────┘ ┴ └───────────┘ ┴ ┴└┘ └┘ └───────────────┘
2027
2028 theorem filter_eq_self {l} : filter p l = l ↔ ∀ a ∈ l, p a :=
id └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └────┘ ┴ ┴
typ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
2029 begin
st └─────
2030 induction l with a l ih,
id ┴
src └────────┘ └──────────┘
typ └────────┘┴└──────────┘
doc └────────┘ └──────────┘
txt └────────┘ └──────────┘
par └────────┘ └──────────┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─
2031 { exact iff_of_true rfl (forall_mem_nil _) },
id └─────────┘ └─┘ └────────────┘
src └────┘└─────────┘┴└─┘┴ └────────────┘└──┘
typ └────┘└─────────┘┴└─┘┴ └────────────┘└──┘
doc └────┘ ┴ ┴ └──┘
txt └────┘ ┴ ┴ └──┘
par └────┘ ┴ ┴ └──┘
pid ┴ ┴ ┴ └─┘┴
st ───┘└───────────────────────────────────────┘└┘└
2032 rw forall_mem_cons, by_cases p a,
id └─────────────┘ ┴ ┴
src └─┘└─────────────┘ └───────┘ ┴
typ └─┘└─────────────┘ └───────┘┴┴┴
doc └─┘ └───────┘ ┴
txt └─┘ └───────┘ ┴
par └─┘ └───────┘ ┴
pid ┴ ┴ ┴
st ───────────────────┘└────────────┘└─
2033 { rw [filter_cons_of_pos _ h, cons_inj', ih, and_iff_right h] },
id └────────────────┘ ┴ └───────┘ └┘ └───────────┘ ┴
src └──┘└────────────────┘└─┘ └┘└───────┘└┘ └┘└───────────┘┴ └┘
typ └──┘└────────────────┘└─┘┴└┘└───────┘└┘└┘└┘└───────────┘┴┴└┘
doc └──┘ └─┘ └┘ └┘ └┘ ┴ └┘
txt └──┘ └─┘ └┘ └┘ └┘ ┴ └┘
par └──┘ └─┘ └┘ └┘ └┘ ┴ └┘
pid └┘ └─┘ └┘ └┘ └┘ ┴ ┴┴
st ───┘└────────────────────────┘└─────────┘└──┘└───────────────┘┴┴└┘└
2034 { rw [filter_cons_of_neg _ h],
id └────────────────┘ ┴
src └──┘└────────────────┘└─┘ ┴
typ └──┘└────────────────┘└─┘┴┴
doc └──┘ └─┘ ┴
txt └──┘ └─┘ ┴
par └──┘ └─┘ ┴
pid └┘ └─┘ ┴
st ─────────────────────────────┘└──
2035 refine iff_of_false _ (mt and.left h), intro e,
id └──────────┘ └┘ └──────┘ ┴
src └─────┘└──────────┘└─┘ └┘┴└──────┘┴ ┴ └─────┘
typ └─────┘└──────────┘└─┘ └┘┴└──────┘┴┴┴ └─────┘
doc └─────┘ └─┘ ┴ ┴ ┴ └─────┘
txt └─────┘ └─┘ ┴ ┴ ┴ └─────┘
par └─────┘ └─┘ ┴ ┴ ┴ └─────┘
pid ┴ └─┘ ┴ ┴ ┴ └┘
st ────────────────────────────────────────┘└───────┘└─
2036 have := filter_sublist l, rw e at this,
id └────────────┘ ┴ ┴
src └──────┘└────────────┘┴ └─┘ └──────┘
typ └──────┘└────────────┘┴┴ └─┘┴└──────┘
doc └──────┘ ┴ └─┘ └──────┘
txt └──────┘ ┴ └─┘ └──────┘
par └──────┘ ┴ └─┘ └──────┘
pid └───┘└─┘ ┴ ┴ └──────┘
st ───────────────────────────┘└────────────┘└─
2037 exact not_lt_of_ge (length_le_of_sublist this) (lt_succ_self _) }
id └──────────┘ └──────────────────┘ └──┘ └──────────┘
src └────┘└──────────┘┴ └──────────────────┘┴ └┘ └──────────┘└──┘
typ └────┘└──────────┘┴ └──────────────────┘┴└──┘└┘ └──────────┘└──┘
doc └────┘ ┴ ┴ └┘ └──┘
txt └────┘ ┴ ┴ └┘ └──┘
par └────┘ ┴ ┴ └┘ └──┘
pid ┴ ┴ ┴ └┘ └─┘┴
st ───────────────────────────────────────────────────────────────────┘└─
2038 end
st ──┘
2039
2040 theorem filter_eq_nil {l} : filter p l = [] ↔ ∀ a ∈ l, ¬p a :=
id └────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴┴ ┴
src └────┘ ┴ └┘ ┴ ┴
typ └────┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴┴ ┴
2041 by simp only [eq_nil_iff_forall_not_mem, mem_filter, not_and]
id └───────────────────────┘ └────────┘ └─────┘
src └─────────┘└───────────────────────┘└┘└────────┘└┘└─────┘└─
typ └─────────┘└───────────────────────┘└┘└────────┘└┘└─────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────────────────
2042
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2043 theorem filter_sublist_filter {l₁ l₂} (s : l₁ <+ l₂) : filter p l₁ <+ filter p l₂ :=
id └┘ └┘ └┘ └────┘ ┴ └┘ └┘ └────┘ ┴ └┘
src └┘ └────┘ └┘ └────┘
typ └┘ └┘ └┘ └────┘ ┴ └┘ └┘ └────┘ ┴ └┘
2044 by rw ← filter_map_eq_filter; exact filter_map_sublist_filter_map _ s
id └──────────────────┘ └───────────────────────────┘ ┴
src └───┘└──────────────────┘ └────┘└───────────────────────────┘└─┘ └
typ └───┘└──────────────────┘ └────┘└───────────────────────────┘└─┘┴└
doc └───┘ └────┘ └─┘ └
txt └───┘ └────┘ └─┘ └
par └───┘ └────┘ └─┘ └
pid └─┘ ┴ └─┘ └
st └───────────────────────────────────────────────────────────────────
2045
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2046 theorem filter_of_map (f : β → α) (l) : filter p (map f l) = map f (filter (p ∘ f) l) :=
id ┴ ┴ └────┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ ┴
src └────┘ └─┘ ┴ └─┘ └────┘ ┴
typ ┴ ┴ └────┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ └────┘ ┴ ┴ ┴ ┴
2047 by rw [← filter_map_eq_map, filter_filter_map, filter_map_filter]; refl
id └───────────────┘ └───────────────┘ └───────────────┘
src └────┘└───────────────┘└┘└───────────────┘└┘└───────────────┘┴ └────
typ └────┘└───────────────┘└┘└───────────────┘└┘└───────────────┘┴ └────
doc └────┘ └┘ └┘ ┴ └────
txt └────┘ └┘ └┘ ┴ └────
par └────┘ └┘ └┘ ┴ └────
pid └──┘ └┘ └┘ ┴ └
st └──────────────────────┘└─────────────────┘└─────────────────┘┴└──────
2048
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2049 @[simp] theorem filter_filter {q} [decidable_pred q] : ∀ l,
id └────────────┘ ┴ ┴
src └────────────┘
typ └────────────┘ ┴ ┴
doc └──┘
2050 filter p (filter q l) = filter (λ a, p a ∧ q a) l
id └────┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └────┘ └────┘ ┴ └────┘ ┴
typ └────┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
2051 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2052 | (a :: l) := by by_cases hp : p a; by_cases hq : q a; simp only [hp, hq, filter, if_true, if_false,
id └┘ ┴ ┴ ┴ ┴ └┘ └┘ └────┘ └─────┘ └──────┘
src └┘ └───────┘ └─┘ ┴ └───────┘ └─┘ ┴ └─────────┘ └┘ └┘└────┘└┘└─────┘└┘└──────┘└─
typ └┘ └───────┘ └─┘┴┴┴ └───────┘ └─┘┴┴┴ └─────────┘└┘└┘└┘└┘└────┘└┘└─────┘└┘└──────┘└─
doc └───────┘ └─┘ ┴ └───────┘ └─┘ ┴ └─────────┘ └┘ └┘ └┘ └┘ └─
txt └───────┘ └─┘ ┴ └───────┘ └─┘ ┴ └─────────┘ └┘ └┘ └┘ └┘ └─
par └───────┘ └─┘ ┴ └───────┘ └─┘ ┴ └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴ └─┘ ┴ ┴ └─┘ ┴ ┴└──┘└┘ └┘ └┘ └┘ └┘ └─
st └────────────────────────────────────────────────────────────────────────────────────
2053 true_and, false_and, filter_filter l, eq_self_iff_true]
id └──────┘ └───────┘ └───────────┘ ┴ └──────────────┘
src ───┘└──────┘└┘└───────┘└┘ ┴ └┘└──────────────┘└─
typ ───┘└──────┘└┘└───────┘└┘└───────────┘┴┴└┘└──────────────┘└─
doc ───┘ └┘ └┘ ┴ └┘ └─
txt ───┘ └┘ └┘ ┴ └┘ └─
par ───┘ └┘ └┘ ┴ └┘ └─
pid ───┘ └┘ └┘ ┴ └┘ ┴└
st ────────────────────────────────────────────────────────────
2054
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2055 @[simp] lemma filter_true {h : decidable_pred (λ a : α, true)} (l : list α) : @filter α (λ _, true) h l = l :=
id └────────────┘ ┴ └──┘ └──┘ ┴ └────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
src └────────────┘ └──┘ └──┘ └────┘ └──┘ ┴
typ └────────────┘ ┴ └──┘ └──┘ ┴ └────┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘
2056 by convert filter_eq_self.2 (λ _ _, trivial)
id └────────────┘ └─────┘
src └──────┘└────────────┘└─┘ └────┘└─────┘└─
typ └──────┘└────────────┘└─┘ └────┘└─────┘└─
doc └──────┘ └─┘ └────┘ └─
txt └──────┘ └─┘ └────┘ └─
par └──────┘ └─┘ └────┘ └─
pid ┴ └─┘ └────┘ ┴└
st └──────────────────────────────────────────
2057
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2058 @[simp] lemma filter_false {h : decidable_pred (λ a : α, false)} (l : list α) : @filter α (λ _, false) h l = [] :=
id └────────────┘ ┴ └───┘ └──┘ ┴ └────┘ ┴ ┴ └───┘ ┴ ┴ ┴ └┘
src └────────────┘ └───┘ └──┘ └────┘ └───┘ ┴ └┘
typ └────────────┘ ┴ └───┘ └──┘ ┴ └────┘ ┴ ┴ └───┘ ┴ ┴ ┴ └┘
doc └──┘
2059 by convert filter_eq_nil.2 (λ _ _, id)
id └───────────┘ └┘
src └──────┘└───────────┘└─┘ └────┘└┘└─
typ └──────┘└───────────┘└─┘ └────┘└┘└─
doc └──────┘ └─┘ └────┘ └─
txt └──────┘ └─┘ └────┘ └─
par └──────┘ └─┘ └────┘ └─
pid ┴ └─┘ └────┘ ┴└
st └────────────────────────────────────
2060
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2061 @[simp] theorem span_eq_take_drop (p : α → Prop) [decidable_pred p] : ∀ (l : list α), span p l = (take_while p l, drop_while p l)
id ┴ └────────────┘ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴└────────┘ ┴ ┴ └────────┘ ┴ ┴
src └────────────┘ └──┘ └──┘ ┴ ┴└────────┘ └────────┘
typ ┴ └────────────┘ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴└────────┘ ┴ ┴ └────────┘ ┴ ┴
doc └──┘ └────────┘
2062 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2063 | (a::l) := if pa : p a then by simp only [span, if_pos pa, span_eq_take_drop l, take_while, drop_while]
id ┴└┘ └┘ ┴ └──┘ └────┘ └┘ └───────────────┘ ┴ └────────┘ └────────┘
src └┘ └┘ └─────────┘└──┘└┘└────┘┴ └┘ ┴ └┘└────────┘└┘└────────┘└─
typ ┴└┘ └┘ ┴ └─────────┘└──┘└┘└────┘┴└┘└┘└───────────────┘┴┴└┘└────────┘└┘└────────┘└─
doc └─────────┘ └┘ ┴ └┘ ┴ └┘└────────┘└┘ └─
txt └─────────┘ └┘ ┴ └┘ ┴ └┘ └┘ └─
par └─────────┘ └┘ ┴ └┘ ┴ └┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴ └┘ ┴ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────────────────
2064 else by simp only [span, take_while, drop_while, if_neg pa]
id └──┘ └────────┘ └────────┘ └────┘ └┘
src ───┘ └─────────┘└──┘└┘└────────┘└┘└────────┘└┘└────┘┴ └─
typ ───┘ └─────────┘└──┘└┘└────────┘└┘└────────┘└┘└────┘┴└┘└─
doc ───┘ └─────────┘ └┘└────────┘└┘ └┘ ┴ └─
txt ───┘ └─────────┘ └┘ └┘ └┘ ┴ └─
par ───┘ └─────────┘ └┘ └┘ └┘ ┴ └─
pid ───┘ ┴└──┘└┘ └┘ └┘ └┘ ┴ ┴└
st ───┘ └────────────────────────────────────────────────────
2065
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2066 @[simp] theorem take_while_append_drop (p : α → Prop) [decidable_pred p] : ∀ (l : list α), take_while p l ++ drop_while p l = l
id ┴ └────────────┘ ┴ ┴ └──┘ ┴ └────────┘ ┴ ┴ └┘ └────────┘ ┴ ┴ ┴ ┴
src └────────────┘ └──┘ └────────┘ └┘ └────────┘ ┴
typ ┴ └────────────┘ ┴ ┴ └──┘ ┴ └────────┘ ┴ ┴ └┘ └────────┘ ┴ ┴ ┴ ┴
doc └──┘ └────────┘
2067 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2068 | (a::l) := if pa : p a then by rw [take_while, drop_while, if_pos pa, if_pos pa, cons_append, take_while_append_drop l]
id ┴└┘ └┘ ┴ └────────┘ └────────┘ └────┘ └┘ └────┘ └┘ └─────────┘ └────────────────────┘ ┴
src └┘ └┘ └──┘└────────┘└┘└────────┘└┘└────┘┴ └┘└────┘┴ └┘└─────────┘└┘ ┴ └─
typ ┴└┘ └┘ ┴ └──┘└────────┘└┘└────────┘└┘└────┘┴└┘└┘└────┘┴└┘└┘└─────────┘└┘└────────────────────┘┴┴└─
doc └──┘└────────┘└┘ └┘ ┴ └┘ ┴ └┘ └┘ ┴ └─
txt └──┘ └┘ └┘ ┴ └┘ ┴ └┘ └┘ ┴ └─
par └──┘ └┘ └┘ ┴ └┘ ┴ └┘ └┘ ┴ └─
pid └┘ └┘ └┘ ┴ └┘ ┴ └┘ └┘ ┴ ┴└
st └─────────────┘└──────────┘└─────────┘└─────────┘└───────────┘└────────────────────────┘┴└
2069 else by rw [take_while, drop_while, if_neg pa, if_neg pa, nil_append]
id └────────┘ └────────┘ └────┘ └┘ └────┘ └┘ └────────┘
src ───┘ └──┘└────────┘└┘└────────┘└┘└────┘┴ └┘└────┘┴ └┘└────────┘└─
typ ───┘ └──┘└────────┘└┘└────────┘└┘└────┘┴└┘└┘└────┘┴└┘└┘└────────┘└─
doc ───┘ └──┘└────────┘└┘ └┘ ┴ └┘ ┴ └┘ └─
txt ───┘ └──┘ └┘ └┘ ┴ └┘ ┴ └┘ └─
par ───┘ └──┘ └┘ └┘ ┴ └┘ ┴ └┘ └─
pid ───┘ └┘ └┘ └┘ ┴ └┘ ┴ └┘ ┴└
st ───┘ └─────────────┘└──────────┘└─────────┘└─────────┘└──────────┘┴└
2070
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2071 @[simp] theorem countp_nil (p : α → Prop) [decidable_pred p] : countp p [] = 0 := rfl
id ┴ └────────────┘ ┴ └────┘ ┴ └┘ ┴ └─┘
src └────────────┘ └────┘ └┘ ┴ └─┘
typ ┴ └────────────┘ ┴ └────┘ ┴ └┘ ┴ └─┘
doc └──┘ └────┘
2072
2073 @[simp] theorem countp_cons_of_pos {a : α} (l) (pa : p a) : countp p (a::l) = countp p l + 1 :=
id ┴ ┴ ┴ └────┘ ┴ ┴└┘┴ ┴ └────┘ ┴ ┴ ┴
src └────┘ └┘ ┴ └────┘ ┴
typ ┴ ┴ ┴ └────┘ ┴ ┴└┘┴ ┴ └────┘ ┴ ┴ ┴
doc └──┘ └────┘ └────┘
2074 if_pos pa
id └────┘ └┘
src └────┘
typ └────┘ └┘
2075
2076 @[simp] theorem countp_cons_of_neg {a : α} (l) (pa : ¬ p a) : countp p (a::l) = countp p l :=
id ┴ ┴ ┴ ┴ └────┘ ┴ ┴└┘┴ ┴ └────┘ ┴ ┴
src ┴ └────┘ └┘ ┴ └────┘
typ ┴ ┴ ┴ ┴ └────┘ ┴ ┴└┘┴ ┴ └────┘ ┴ ┴
doc └──┘ └────┘ └────┘
2077 if_neg pa
id └────┘ └┘
src └────┘
typ └────┘ └┘
2078
2079 theorem countp_eq_length_filter (l) : countp p l = length (filter p l) :=
id └────┘ ┴ ┴ ┴ └────┘ └────┘ ┴ ┴
src └────┘ ┴ └────┘ └────┘
typ └────┘ ┴ ┴ ┴ └────┘ └────┘ ┴ ┴
doc └────┘
2080 by induction l with x l ih; [refl, by_cases (p x)]; [simp only [filter_cons_of_pos _ h, countp, ih, if_pos h],
id ┴ ┴ ┴ ┴ ┴ └────────────────┘ ┴ └────┘ └┘ └────┘ ┴
src └────────┘ └──────────┘ ┴└──┘ └───────┘ ┴ ┴ ┴└─────────┘└────────────────┘└─┘ └┘└────┘└┘ └┘└────┘┴ ┴
typ └────────┘┴└──────────┘ ┴└──┘ └───────┘ ┴┴┴┴ ┴└─────────┘└────────────────┘└─┘┴└┘└────┘└┘└┘└┘└────┘┴┴┴
doc └────────┘ └──────────┘ └──┘ └───────┘ ┴ ┴ └─────────┘ └─┘ └┘└────┘└┘ └┘ ┴ ┴
txt └────────┘ └──────────┘ └──┘ └───────┘ ┴ ┴ └─────────┘ └─┘ └┘ └┘ └┘ ┴ ┴
par └────────┘ └──────────┘ └──┘ └───────┘ ┴ ┴ └─────────┘ └─┘ └┘ └┘ └┘ ┴ ┴
pid ┴ ┴└─────────┘ ┴ ┴ ┴ ┴└──┘└┘ └─┘ └┘ └┘ └┘ ┴ ┴
st └────────────────────────────────────────────────────────────────────────────────────────────────────────────
2081 simp only [countp_cons_of_neg _ h, ih, filter_cons_of_neg _ h]]; refl
id └────────────────┘ ┴ └┘ └────────────────┘ ┴
src └─────────┘└────────────────┘└─┘ └┘ └┘└────────────────┘└─┘ ┴ └───┘
typ └─────────┘└────────────────┘└─┘┴└┘└┘└┘└────────────────┘└─┘┴┴ └───┘
doc └─────────┘ └─┘ └┘ └┘ └─┘ ┴ └───┘
txt └─────────┘ └─┘ └┘ └┘ └─┘ ┴ └───┘
par └─────────┘ └─┘ └┘ └┘ └─┘ ┴ └───┘
pid ┴└──┘└┘ └─┘ └┘ └┘ └─┘ ┴ ┴
st ───────────────────────────────────────────────────────────────────────┘
2082 local attribute [simp] countp_eq_length_filter
id └─────────────────────┘
src └─────────────────────┘
typ └─────────────────────┘
doc └──┘
2083
2084 @[simp] theorem countp_append (l₁ l₂) : countp p (l₁ ++ l₂) = countp p l₁ + countp p l₂ :=
id └────┘ ┴ └┘ └┘ └┘ ┴ └────┘ ┴ └┘ ┴ └────┘ ┴ └┘
src └────┘ └┘ ┴ └────┘ ┴ └────┘
typ └────┘ ┴ └┘ └┘ └┘ ┴ └────┘ ┴ └┘ ┴ └────┘ ┴ └┘
doc └──┘ └────┘ └────┘ └────┘
2085 by simp only [countp_eq_length_filter, filter_append, length_append]
id └─────────────────────┘ └───────────┘ └───────────┘
src └─────────┘└─────────────────────┘└┘└───────────┘└┘└───────────┘└─
typ └─────────┘└─────────────────────┘└┘└───────────┘└┘└───────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └──────────────────────────────────────────────────────────────────
2086
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2087 theorem countp_pos {l} : 0 < countp p l ↔ ∃ a ∈ l, p a :=
id ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
src ┴ └────┘ ┴ ┴ ┴
typ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
doc └────┘
2088 by simp only [countp_eq_length_filter, length_pos_iff_exists_mem, mem_filter, exists_prop]
id └─────────────────────┘ └───────────────────────┘ └────────┘ └─────────┘
src └─────────┘└─────────────────────┘└┘└───────────────────────┘└┘└────────┘└┘└─────────┘└─
typ └─────────┘└─────────────────────┘└┘└───────────────────────┘└┘└────────┘└┘└─────────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────────────────────────────
2089
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2090 theorem countp_le_of_sublist {l₁ l₂} (s : l₁ <+ l₂) : countp p l₁ ≤ countp p l₂ :=
id └┘ └┘ └┘ └────┘ ┴ └┘ ┴ └────┘ ┴ └┘
src └┘ └────┘ ┴ └────┘
typ └┘ └┘ └┘ └────┘ ┴ └┘ ┴ └────┘ ┴ └┘
doc └────┘ └────┘
2091 by simpa only [countp_eq_length_filter] using length_le_of_sublist (filter_sublist_filter s)
id └─────────────────────┘ └──────────────────┘ └───────────────────┘ ┴
src └──────────┘└─────────────────────┘└──────┘└──────────────────┘┴ └───────────────────┘┴ └─
typ └──────────┘└─────────────────────┘└──────┘└──────────────────┘┴ └───────────────────┘┴┴└─
doc └──────────┘ └──────┘ ┴ ┴ └─
txt └──────────┘ └──────┘ ┴ ┴ └─
par └──────────┘ └──────┘ ┴ ┴ └─
pid ┴└──┘└┘ ┴┴└────┘ ┴ ┴ ┴└
st └──────────────────────────────────────────────────────────────────────────────────────────
2092
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2093 @[simp] theorem countp_filter {q} [decidable_pred q] (l : list α) :
id └────────────┘ ┴ └──┘ ┴
src └────────────┘ └──┘
typ └────────────┘ ┴ └──┘ ┴
doc └──┘
2094 countp p (filter q l) = countp (λ a, p a ∧ q a) l :=
id └────┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └────┘ └────┘ ┴ └────┘ ┴
typ └────┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └────┘ └────┘
2095 by simp only [countp_eq_length_filter, filter_filter]
id └─────────────────────┘ └───────────┘
src └─────────┘└─────────────────────┘└┘└───────────┘└─
typ └─────────┘└─────────────────────┘└┘└───────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └───────────────────────────────────────────────────
2096
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2097 end filter
2098
2099 /- count -/
2100
2101 section count
2102 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
2103
2104 @[simp] theorem count_nil (a : α) : count a [] = 0 := rfl
id ┴ └───┘ ┴ └┘ ┴ └─┘
src └───┘ └┘ ┴ └─┘
typ ┴ └───┘ ┴ └┘ ┴ └─┘
doc └──┘ └───┘
2105
2106 theorem count_cons (a b : α) (l : list α) :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
2107 count a (b :: l) = if a = b then succ (count a l) else count a l := rfl
id └───┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └──┘ └───┘ ┴ ┴ └───┘ ┴ ┴ └─┘
src └───┘ └┘ ┴ ┴ └──┘ └───┘ └───┘ └─┘
typ └───┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └──┘ └───┘ ┴ ┴ └───┘ ┴ ┴ └─┘
doc └───┘ └───┘ └───┘
2108
2109 theorem count_cons' (a b : α) (l : list α) :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
2110 count a (b :: l) = count a l + (if a = b then 1 else 0) :=
id └───┘ ┴ ┴ └┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
src └───┘ └┘ ┴ └───┘ ┴ ┴
typ └───┘ ┴ ┴ └┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └───┘ └───┘
2111 begin rw count_cons, split_ifs; refl end
id └────────┘
src └─┘└────────┘ └───────┘ └───┘
typ └─┘└────────┘ └───────┘ └───┘
doc └─┘ └───────┘ └───┘
txt └─┘ └───────┘ └───┘
par └─┘ └───────┘ └───┘
pid ┴ ┴
st └─────────────────┘└────────────────┘└─┘
2112
2113 @[simp] theorem count_cons_self (a : α) (l : list α) : count a (a::l) = succ (count a l) :=
id ┴ └──┘ ┴ └───┘ ┴ ┴└┘┴ ┴ └──┘ └───┘ ┴ ┴
src └──┘ └───┘ └┘ ┴ └──┘ └───┘
typ ┴ └──┘ ┴ └───┘ ┴ ┴└┘┴ ┴ └──┘ └───┘ ┴ ┴
doc └──┘ └───┘ └───┘
2114 if_pos rfl
id └────┘ └─┘
src └────┘ └─┘
typ └────┘ └─┘
2115
2116 @[simp] theorem count_cons_of_ne {a b : α} (h : a ≠ b) (l : list α) : count a (b::l) = count a l :=
id ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴
src ┴ └──┘ └───┘ └┘ ┴ └───┘
typ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴└┘┴ ┴ └───┘ ┴ ┴
doc └──┘ └───┘ └───┘
2117 if_neg h
id └────┘ ┴
src └────┘
typ └────┘ ┴
2118
2119 theorem count_tail : Π (l : list α) (a : α) (h : 0 < l.length),
id ┴ └──┘ ┴ ┴ ┴ ┴└─────┘
src └──┘ ┴ └─────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴└─────┘
2120 l.tail.count a = l.count a - ite (a = list.nth_le l 0 h) 1 0
id ┴└───┘└────┘ ┴ ┴ ┴└────┘ ┴ ┴ └─┘ ┴ ┴ └─────────┘ ┴ ┴
src └───┘└────┘ ┴ └────┘ ┴ └─┘ ┴ └─────────┘
typ ┴└───┘└────┘ ┴ ┴ ┴└────┘ ┴ ┴ └─┘ ┴ ┴ └─────────┘ ┴ ┴
doc └────┘ └────┘
2121 | (_ :: _) a h := by { rw [count_cons], split_ifs; simp }
id └┘ └────────┘
src └┘ └──┘└────────┘┴ └───────┘ └───┘
typ └┘ └──┘└────────┘┴ └───────┘ └───┘
doc └──┘ ┴ └───────┘ └───┘
txt └──┘ ┴ └───────┘ └───┘
par └──┘ ┴ └───────┘ └───┘
pid └┘ ┴ ┴
st └───────────────┘└─────────────────┘└┘
2122
2123 theorem count_le_of_sublist (a : α) {l₁ l₂} : l₁ <+ l₂ → count a l₁ ≤ count a l₂ :=
id ┴ └┘ └┘ └┘ └───┘ ┴ └┘ ┴ └───┘ ┴ └┘
src └┘ └───┘ ┴ └───┘
typ ┴ └┘ └┘ └┘ └───┘ ┴ └┘ ┴ └───┘ ┴ └┘
doc └───┘ └───┘
2124 countp_le_of_sublist
id └──────────────────┘
src └──────────────────┘
typ └──────────────────┘
2125
2126 theorem count_le_count_cons (a b : α) (l : list α) : count a l ≤ count a (b :: l) :=
id ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴
src └──┘ └───┘ ┴ └───┘ └┘
typ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ └┘ ┴
doc └───┘ └───┘
2127 count_le_of_sublist _ (sublist_cons _ _)
id └─────────────────┘ └──────────┘
src └─────────────────┘ └──────────┘
typ └─────────────────┘ └──────────┘
2128
2129 theorem count_singleton (a : α) : count a [a] = 1 := if_pos rfl
id ┴ └───┘ ┴ ┴┴┴ ┴ └────┘ └─┘
src └───┘ ┴ ┴ ┴ └────┘ └─┘
typ ┴ └───┘ ┴ ┴┴┴ ┴ └────┘ └─┘
doc └───┘
2130
2131 @[simp] theorem count_append (a : α) : ∀ l₁ l₂, count a (l₁ ++ l₂) = count a l₁ + count a l₂ :=
id ┴ └┘ └┘ └───┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ └┘ ┴ └───┘ ┴ └┘
src └───┘ └┘ ┴ └───┘ ┴ └───┘
typ ┴ └┘ └┘ └───┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ └┘ ┴ └───┘ ┴ └┘
doc └──┘ └───┘ └───┘ └───┘
2132 countp_append
id └───────────┘
src └───────────┘
typ └───────────┘
2133
2134 @[simp] theorem count_concat (a : α) (l : list α) : count a (concat l a) = succ (count a l) :=
id ┴ └──┘ ┴ └───┘ ┴ └────┘ ┴ ┴ ┴ └──┘ └───┘ ┴ ┴
src └──┘ └───┘ └────┘ ┴ └──┘ └───┘
typ ┴ └──┘ ┴ └───┘ ┴ └────┘ ┴ ┴ ┴ └──┘ └───┘ ┴ ┴
doc └──┘ └───┘ └────┘ └───┘
2135 by rw [concat_eq_append, count_append, count_singleton]
id └──────────────┘ └──────────┘ └─────────────┘
src └──┘└──────────────┘└┘└──────────┘└┘└─────────────┘└─
typ └──┘└──────────────┘└┘└──────────┘└┘└─────────────┘└─
doc └──┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └───────────────────┘└────────────┘└───────────────┘┴└
2136
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2137 theorem count_pos {a : α} {l : list α} : 0 < count a l ↔ a ∈ l :=
id ┴ └──┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └───┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └───┘
2138 by simp only [count, countp_pos, exists_prop, exists_eq_right']
id └───┘ └────────┘ └─────────┘ └──────────────┘
src └─────────┘└───┘└┘└────────┘└┘└─────────┘└┘└──────────────┘└─
typ └─────────┘└───┘└┘└────────┘└┘└─────────┘└┘└──────────────┘└─
doc └─────────┘└───┘└┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────
2139
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2140 @[simp] theorem count_eq_zero_of_not_mem {a : α} {l : list α} (h : a ∉ l) : count a l = 0 :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └──┘ ┴ └───┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc └──┘ └───┘
2141 by_contradiction $ λ h', h $ count_pos.1 (nat.pos_of_ne_zero h')
id └──────────────┘ └┘ ┴ └───────┘┴ └────────────────┘ └┘
src └──────────────┘ └───────┘┴ └────────────────┘
typ └──────────────┘ └┘ ┴ └───────┘┴ └────────────────┘ └┘
2142
2143 theorem not_mem_of_count_eq_zero {a : α} {l : list α} (h : count a l = 0) : a ∉ l :=
id ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └───┘ ┴ ┴
typ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └───┘
2144 λ h', ne_of_gt (count_pos.2 h') h
id └┘ └──────┘ └───────┘┴ └┘ ┴
src └──────┘ └───────┘┴
typ └┘ └──────┘ └───────┘┴ └┘ ┴
2145
2146 @[simp] theorem count_repeat (a : α) (n : ℕ) : count a (repeat a n) = n :=
id ┴ ┴ └───┘ ┴ └────┘ ┴ ┴ ┴ ┴
src ┴ └───┘ └────┘ ┴
typ ┴ ┴ └───┘ ┴ └────┘ ┴ ┴ ┴ ┴
doc └──┘ └───┘
2147 by rw [count, countp_eq_length_filter, filter_eq_self.2, length_repeat];
id └───┘ └─────────────────────┘ └────────────┘ └───────────┘
src └──┘└───┘└┘└─────────────────────┘└┘└────────────┘└──┘└───────────┘┴
typ └──┘└───┘└┘└─────────────────────┘└┘└────────────┘└──┘└───────────┘┴
doc └──┘└───┘└┘ └┘ └──┘ ┴
txt └──┘ └┘ └┘ └──┘ ┴
par └──┘ └┘ └┘ └──┘ ┴
pid └┘ └┘ └┘ └──┘ ┴
st └────────┘└───────────────────────┘└──────────────┘└───────────────┘┴└─
2148 exact λ b m, (eq_of_mem_repeat m).symm
id └──────────────┘
src └────┘ └────┘ └──────────────┘┴ └──────
typ └────┘ └────┘ └──────────────┘┴ └──────
doc └────┘ └────┘ ┴ └──────
txt └────┘ └────┘ ┴ └──────
par └────┘ └────┘ ┴ └──────
pid ┴ └────┘ ┴ └───┘└─
st ──────────────────────────────────────────
2149
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2150 theorem le_count_iff_repeat_sublist {a : α} {l : list α} {n : ℕ} : n ≤ count a l ↔ repeat a n <+ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴
src └──┘ ┴ ┴ └───┘ ┴ └────┘ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴
doc └───┘
2151 ⟨λ h, ((repeat_sublist_repeat a).2 h).trans $
id ┴ └───────────────────┘ ┴ ┴ ┴ └───┘
src └───────────────────┘ ┴ └───┘
typ ┴ └───────────────────┘ ┴ ┴ ┴ └───┘
2152 have filter (eq a) l = repeat a (count a l), from eq_repeat.2
id └────┘ └┘ ┴ ┴ ┴ └────┘ ┴ └───┘ ┴ ┴ └───────┘┴
src └────┘ └┘ ┴ └────┘ └───┘ └───────┘┴
typ └────┘ └┘ ┴ ┴ ┴ └────┘ ┴ └───┘ ┴ ┴ └───────┘┴
doc └───┘
2153 ⟨by simp only [count, countp_eq_length_filter], λ b m, (of_mem_filter m).symm⟩,
id └───┘ └─────────────────────┘ ┴ ┴ └───────────┘ ┴ └──┘
src └─────────┘└───┘└┘└─────────────────────┘┴ └───────────┘ └──┘
typ └─────────┘└───┘└┘└─────────────────────┘┴ ┴ ┴ └───────────┘ ┴ └──┘
doc └─────────┘└───┘└┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st └─────────────────────────────────────────┘
2154 by rw ← this; apply filter_sublist,
id └──┘ └────────────┘
src └───┘ └────┘└────────────┘
typ └───┘└──┘ └────┘└────────────┘
doc └───┘ └────┘
txt └───┘ └────┘
par └───┘ └────┘
pid └─┘ ┴
st └──────────────────────────────┘
2155 λ h, by simpa only [count_repeat] using count_le_of_sublist a h⟩
id ┴ └──────────┘ └─────────────────┘ ┴ ┴
src └──────────┘└──────────┘└──────┘└─────────────────┘┴ ┴
typ ┴ └──────────┘└──────────┘└──────┘└─────────────────┘┴┴┴┴
doc └──────────┘ └──────┘ ┴ ┴
txt └──────────┘ └──────┘ ┴ ┴
par └──────────┘ └──────┘ ┴ ┴
pid ┴└──┘└┘ ┴┴└────┘ ┴ ┴
st └──────────────────────────────────────────────────────┘
2156
2157 @[simp] theorem count_filter {p} [decidable_pred p]
id └────────────┘ ┴
src └────────────┘
typ └────────────┘ ┴
doc └──┘
2158 {a} {l : list α} (h : p a) : count a (filter p l) = count a l :=
id └──┘ ┴ ┴ ┴ └───┘ ┴ └────┘ ┴ ┴ ┴ └───┘ ┴ ┴
src └──┘ └───┘ └────┘ ┴ └───┘
typ └──┘ ┴ ┴ ┴ └───┘ ┴ └────┘ ┴ ┴ ┴ └───┘ ┴ ┴
doc └───┘ └───┘
2159 by simp only [count, countp_filter]; congr; exact
id └───┘ └───────────┘
src └─────────┘└───┘└┘└───────────┘┴ └───┘ └────┘
typ └─────────┘└───┘└┘└───────────┘┴ └───┘ └────┘
doc └─────────┘└───┘└┘ ┴ └────┘
txt └─────────┘ └┘ ┴ └───┘ └────┘
par └─────────┘ └┘ ┴ └───┘ └────┘
pid ┴└──┘└┘ └┘ ┴ ┴
st └───────────────────────────────────────────────
2160 set.ext (λ b, and_iff_left_of_imp (λ e, e ▸ h))
id └─────┘ └─────────────────┘ ┴ ┴
src └─────┘┴ └──┘└─────────────────┘┴ └──┘ ┴┴┴ └──
typ └─────┘┴ └──┘└─────────────────┘┴ └──┘ ┴┴┴┴└──
doc ┴ └──┘ ┴ └──┘ ┴ ┴ └──
txt ┴ └──┘ ┴ └──┘ ┴ ┴ └──
par ┴ └──┘ ┴ └──┘ ┴ ┴ └──
pid ┴ └──┘ ┴ └──┘ ┴ ┴ └┘└
st ────────────────────────────────────────────────
2161
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2162 end count
2163
2164 /- prefix, suffix, infix -/
2165
2166 @[simp] theorem prefix_append (l₁ l₂ : list α) : l₁ <+: l₁ ++ l₂ := ⟨l₂, rfl⟩
id └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘ └─┘
src └──┘ └─┘ └┘ └─┘
typ └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘ └─┘
doc └──┘ └─┘
2167
2168 @[simp] theorem suffix_append (l₁ l₂ : list α) : l₂ <:+ l₁ ++ l₂ := ⟨l₁, rfl⟩
id └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘ └─┘
src └──┘ └─┘ └┘ └─┘
typ └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘ └─┘
doc └──┘ └─┘
2169
2170 @[simp] theorem infix_append (l₁ l₂ l₃ : list α) : l₂ <:+: l₁ ++ l₂ ++ l₃ := ⟨l₁, l₃, rfl⟩
id └──┘ ┴ └┘ └──┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └─┘
src └──┘ └──┘ └┘ └┘ └─┘
typ └──┘ ┴ └┘ └──┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └─┘
doc └──┘ └──┘
2171
2172 theorem nil_prefix (l : list α) : [] <+: l := ⟨l, rfl⟩
id └──┘ ┴ └┘ └─┘ ┴ ┴ └─┘
src └──┘ └┘ └─┘ └─┘
typ └──┘ ┴ └┘ └─┘ ┴ ┴ └─┘
doc └─┘
2173
2174 theorem nil_suffix (l : list α) : [] <:+ l := ⟨l, append_nil _⟩
id └──┘ ┴ └┘ └─┘ ┴ ┴ └────────┘
src └──┘ └┘ └─┘ └────────┘
typ └──┘ ┴ └┘ └─┘ ┴ ┴ └────────┘
doc └─┘
2175
2176 @[refl] theorem prefix_refl (l : list α) : l <+: l := ⟨[], append_nil _⟩
id └──┘ ┴ ┴ └─┘ ┴ └┘ └────────┘
src └──┘ └──┘ └─┘ └┘ └────────┘
typ └──┘ ┴ ┴ └─┘ ┴ └┘ └────────┘
doc └──┘ └─┘
2177
2178 @[refl] theorem suffix_refl (l : list α) : l <:+ l := ⟨[], rfl⟩
id └──┘ ┴ ┴ └─┘ ┴ └┘ └─┘
src └──┘ └──┘ └─┘ └┘ └─┘
typ └──┘ ┴ ┴ └─┘ ┴ └┘ └─┘
doc └──┘ └─┘
2179
2180 @[simp] theorem suffix_cons (a : α) : ∀ l, l <:+ a :: l := suffix_append [a]
id ┴ ┴ ┴ └─┘ ┴ └┘ ┴ └───────────┘ ┴┴┴
src └─┘ └┘ └───────────┘ ┴ ┴
typ ┴ ┴ ┴ └─┘ ┴ └┘ ┴ └───────────┘ ┴┴┴
doc └──┘ └─┘
2181
2182 @[simp] theorem prefix_concat (a : α) (l) : l <+: concat l a :=
id ┴ ┴ └─┘ └────┘ ┴ ┴
src └─┘ └────┘
typ ┴ ┴ └─┘ └────┘ ┴ ┴
doc └──┘ └─┘ └────┘
2183 by simp only [concat_eq_append, prefix_append]
id └──────────────┘ └───────────┘
src └─────────┘└──────────────┘└┘└───────────┘└─
typ └─────────┘└──────────────┘└┘└───────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────────────────────
2184
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2185 theorem infix_of_prefix {l₁ l₂ : list α} : l₁ <+: l₂ → l₁ <:+: l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ └┘ └──┘ └┘
src └──┘ └─┘ └──┘
typ └──┘ ┴ └┘ └─┘ └┘ └┘ └──┘ └┘
doc └─┘ └──┘
2186 λ⟨t, h⟩, ⟨[], t, h⟩
id ┴┴ ┴ └┘
src └┘
typ ┴┴ ┴ └┘
2187
2188 theorem infix_of_suffix {l₁ l₂ : list α} : l₁ <:+ l₂ → l₁ <:+: l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ └┘ └──┘ └┘
src └──┘ └─┘ └──┘
typ └──┘ ┴ └┘ └─┘ └┘ └┘ └──┘ └┘
doc └─┘ └──┘
2189 λ⟨t, h⟩, ⟨t, [], by simp only [h, append_nil]⟩
id ┴┴ └┘ ┴ └────────┘
src └┘ └─────────┘ └┘└────────┘┴
typ ┴┴ └┘ └─────────┘┴└┘└────────┘┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st └────────────────────────┘
2190
2191 @[refl] theorem infix_refl (l : list α) : l <:+: l := infix_of_prefix $ prefix_refl l
id └──┘ ┴ ┴ └──┘ ┴ └─────────────┘ └─────────┘ ┴
src └──┘ └──┘ └──┘ └─────────────┘ └─────────┘
typ └──┘ ┴ ┴ └──┘ ┴ └─────────────┘ └─────────┘ ┴
doc └──┘ └──┘
2192
2193 theorem nil_infix (l : list α) : [] <:+: l := infix_of_prefix $ nil_prefix l
id └──┘ ┴ └┘ └──┘ ┴ └─────────────┘ └────────┘ ┴
src └──┘ └┘ └──┘ └─────────────┘ └────────┘
typ └──┘ ┴ └┘ └──┘ ┴ └─────────────┘ └────────┘ ┴
doc └──┘
2194
2195 theorem infix_cons {L₁ L₂ : list α} {x : α} : L₁ <:+: L₂ → L₁ <:+: x :: L₂ :=
id └──┘ ┴ ┴ └┘ └──┘ └┘ └┘ └──┘ ┴ └┘ └┘
src └──┘ └──┘ └──┘ └┘
typ └──┘ ┴ ┴ └┘ └──┘ └┘ └┘ └──┘ ┴ └┘ └┘
doc └──┘ └──┘
2196 λ⟨LP, LS, H⟩, ⟨x :: LP, LS, H ▸ rfl⟩
id ┴└┘ └┘ ┴ ┴ └┘ ┴ └─┘
src └┘ ┴ └─┘
typ ┴└┘ └┘ ┴ ┴ └┘ ┴ └─┘
2197
2198 @[trans] theorem is_prefix.trans : ∀ {l₁ l₂ l₃ : list α}, l₁ <+: l₂ → l₂ <+: l₃ → l₁ <+: l₃
id ┴ └──┘ ┴ └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘
src └───┘ └──┘ └─┘ └─┘ └─┘
typ ┴ └──┘ ┴ └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘
doc └───┘ └─┘ └─┘ └─┘
2199 | l ._ ._ ⟨r₁, rfl⟩ ⟨r₂, rfl⟩ := ⟨r₁ ++ r₂, (append_assoc _ _ _).symm⟩
id └┘ └┘ └─┘ └┘ └──────────┘ └──┘
src └─┘ └┘ └──────────┘ └──┘
typ └┘ └┘ └─┘ └┘ └──────────┘ └──┘
2200
2201 @[trans] theorem is_suffix.trans : ∀ {l₁ l₂ l₃ : list α}, l₁ <:+ l₂ → l₂ <:+ l₃ → l₁ <:+ l₃
id ┴ └──┘ ┴ └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘
src └───┘ └──┘ └─┘ └─┘ └─┘
typ ┴ └──┘ ┴ └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘
doc └───┘ └─┘ └─┘ └─┘
2202 | l ._ ._ ⟨l₁, rfl⟩ ⟨l₂, rfl⟩ := ⟨l₂ ++ l₁, append_assoc _ _ _⟩
id └┘ └┘ └─┘ └┘ └──────────┘
src └─┘ └┘ └──────────┘
typ └┘ └┘ └─┘ └┘ └──────────┘
2203
2204 @[trans] theorem is_infix.trans : ∀ {l₁ l₂ l₃ : list α}, l₁ <:+: l₂ → l₂ <:+: l₃ → l₁ <:+: l₃
id ┴ └──┘ ┴ └┘ └──┘ └┘ └┘ └──┘ └┘ └┘ └──┘ └┘
src └───┘ └──┘ └──┘ └──┘ └──┘
typ ┴ └──┘ ┴ └┘ └──┘ └┘ └┘ └──┘ └┘ └┘ └──┘ └┘
doc └───┘ └──┘ └──┘ └──┘
2205 | l ._ ._ ⟨l₁, r₁, rfl⟩ ⟨l₂, r₂, rfl⟩ := ⟨l₂ ++ l₁, r₁ ++ r₂, by simp only [append_assoc]⟩
id └┘ └┘ └┘ └┘ └─┘ └┘ └┘ └──────────┘
src └─┘ └┘ └┘ └─────────┘└──────────┘┴
typ └┘ └┘ └┘ └┘ └─┘ └┘ └┘ └─────────┘└──────────┘┴
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid ┴└──┘└┘ ┴
st └───────────────────────┘
2206
2207 theorem sublist_of_infix {l₁ l₂ : list α} : l₁ <:+: l₂ → l₁ <+ l₂ :=
id └──┘ ┴ └┘ └──┘ └┘ └┘ └┘ └┘
src └──┘ └──┘ └┘
typ └──┘ ┴ └┘ └──┘ └┘ └┘ └┘ └┘
doc └──┘
2208 λ⟨s, t, h⟩, by rw [← h]; exact (sublist_append_right _ _).trans (sublist_append_left _ _)
id ┴ ┴ └──────────────────┘ └─────────────────┘
src └────┘ ┴ └────┘ └──────────────────┘└──────────┘ └─────────────────┘└─────
typ ┴ └────┘┴┴ └────┘ └──────────────────┘└──────────┘ └─────────────────┘└─────
doc └────┘ ┴ └────┘ └──────────┘ └─────
txt └────┘ ┴ └────┘ └──────────┘ └─────
par └────┘ ┴ └────┘ └──────────┘ └─────
pid └──┘ ┴ ┴ └──────────┘ └───┘└
st └──────┘┴└──────────────────────────────────────────────────────────────────
2209
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2210 theorem sublist_of_prefix {l₁ l₂ : list α} : l₁ <+: l₂ → l₁ <+ l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘
src └──┘ └─┘ └┘
typ └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘
doc └─┘
2211 sublist_of_infix ∘ infix_of_prefix
id └──────────────┘ ┴ └─────────────┘
src └──────────────┘ ┴ └─────────────┘
typ └──────────────┘ ┴ └─────────────┘
2212
2213 theorem sublist_of_suffix {l₁ l₂ : list α} : l₁ <:+ l₂ → l₁ <+ l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘
src └──┘ └─┘ └┘
typ └──┘ ┴ └┘ └─┘ └┘ └┘ └┘ └┘
doc └─┘
2214 sublist_of_infix ∘ infix_of_suffix
id └──────────────┘ ┴ └─────────────┘
src └──────────────┘ ┴ └─────────────┘
typ └──────────────┘ ┴ └─────────────┘
2215
2216 theorem reverse_suffix {l₁ l₂ : list α} : reverse l₁ <:+ reverse l₂ ↔ l₁ <+: l₂ :=
id └──┘ ┴ └─────┘ └┘ └─┘ └─────┘ └┘ ┴ └┘ └─┘ └┘
src └──┘ └─────┘ └─┘ └─────┘ ┴ └─┘
typ └──┘ ┴ └─────┘ └┘ └─┘ └─────┘ └┘ ┴ └┘ └─┘ └┘
doc └─┘ └─┘
2217 ⟨λ ⟨r, e⟩, ⟨reverse r,
id ┴┴ └─────┘
src └─────┘
typ ┴┴ └─────┘
2218 by rw [← reverse_reverse l₁, ← reverse_append, e, reverse_reverse]⟩,
id └─────────────┘ └┘ └────────────┘ ┴ └─────────────┘
src └────┘└─────────────┘┴ └──┘└────────────┘└┘ └┘└─────────────┘┴
typ └────┘└─────────────┘┴└┘└──┘└────────────┘└┘┴└┘└─────────────┘┴
doc └────┘ ┴ └──┘ └┘ └┘ ┴
txt └────┘ ┴ └──┘ └┘ └┘ ┴
par └────┘ ┴ └──┘ └┘ └┘ ┴
pid └──┘ ┴ └──┘ └┘ └┘ ┴
st └───────────────────────┘└────────────────┘└─┘└───────────────┘┴
2219 λ ⟨r, e⟩, ⟨reverse r, by rw [← reverse_append, e]⟩⟩
id ┴┴ └─────┘ └────────────┘ ┴
src └─────┘ └────┘└────────────┘└┘ ┴
typ ┴┴ └─────┘ └────┘└────────────┘└┘┴┴
doc └────┘ └┘ ┴
txt └────┘ └┘ ┴
par └────┘ └┘ ┴
pid └──┘ └┘ ┴
st └───────────────────┘└─┘┴
2220
2221 theorem reverse_prefix {l₁ l₂ : list α} : reverse l₁ <+: reverse l₂ ↔ l₁ <:+ l₂ :=
id └──┘ ┴ └─────┘ └┘ └─┘ └─────┘ └┘ ┴ └┘ └─┘ └┘
src └──┘ └─────┘ └─┘ └─────┘ ┴ └─┘
typ └──┘ ┴ └─────┘ └┘ └─┘ └─────┘ └┘ ┴ └┘ └─┘ └┘
doc └─┘ └─┘
2222 by rw ← reverse_suffix; simp only [reverse_reverse]
id └────────────┘ └─────────────┘
src └───┘└────────────┘ └─────────┘└─────────────┘└─
typ └───┘└────────────┘ └─────────┘└─────────────┘└─
doc └───┘ └─────────┘ └─
txt └───┘ └─────────┘ └─
par └───┘ └─────────┘ └─
pid └─┘ ┴└──┘└┘ ┴└
st └─────────────────────────────────────────────────
2223
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2224 theorem length_le_of_infix {l₁ l₂ : list α} (s : l₁ <:+: l₂) : length l₁ ≤ length l₂ :=
id └──┘ ┴ └┘ └──┘ └┘ └────┘ └┘ ┴ └────┘ └┘
src └──┘ └──┘ └────┘ ┴ └────┘
typ └──┘ ┴ └┘ └──┘ └┘ └────┘ └┘ ┴ └────┘ └┘
doc └──┘
2225 length_le_of_sublist $ sublist_of_infix s
id └──────────────────┘ └──────────────┘ ┴
src └──────────────────┘ └──────────────┘
typ └──────────────────┘ └──────────────┘ ┴
2226
2227 theorem eq_nil_of_infix_nil {l : list α} (s : l <:+: []) : l = [] :=
id └──┘ ┴ ┴ └──┘ └┘ ┴ ┴ └┘
src └──┘ └──┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ └──┘ └┘ ┴ ┴ └┘
doc └──┘
2228 eq_nil_of_sublist_nil $ sublist_of_infix s
id └───────────────────┘ └──────────────┘ ┴
src └───────────────────┘ └──────────────┘
typ └───────────────────┘ └──────────────┘ ┴
2229
2230 theorem eq_nil_of_prefix_nil {l : list α} (s : l <+: []) : l = [] :=
id └──┘ ┴ ┴ └─┘ └┘ ┴ ┴ └┘
src └──┘ └─┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ └─┘ └┘ ┴ ┴ └┘
doc └─┘
2231 eq_nil_of_infix_nil $ infix_of_prefix s
id └─────────────────┘ └─────────────┘ ┴
src └─────────────────┘ └─────────────┘
typ └─────────────────┘ └─────────────┘ ┴
2232
2233 theorem eq_nil_of_suffix_nil {l : list α} (s : l <:+ []) : l = [] :=
id └──┘ ┴ ┴ └─┘ └┘ ┴ ┴ └┘
src └──┘ └─┘ └┘ ┴ └┘
typ └──┘ ┴ ┴ └─┘ └┘ ┴ ┴ └┘
doc └─┘
2234 eq_nil_of_infix_nil $ infix_of_suffix s
id └─────────────────┘ └─────────────┘ ┴
src └─────────────────┘ └─────────────┘
typ └─────────────────┘ └─────────────┘ ┴
2235
2236 theorem infix_iff_prefix_suffix (l₁ l₂ : list α) : l₁ <:+: l₂ ↔ ∃ t, l₁ <+: t ∧ t <:+ l₂ :=
id └──┘ ┴ └┘ └──┘ └┘ ┴ ┴ ┴┴ └┘ └─┘ ┴ ┴ ┴ └─┘ └┘
src └──┘ └──┘ ┴ ┴ ┴ └─┘ ┴ └─┘
typ └──┘ ┴ └┘ └──┘ └┘ ┴ ┴ ┴┴ └┘ └─┘ ┴ ┴ ┴ └─┘ └┘
doc └──┘ └─┘ └─┘
2237 ⟨λ⟨s, t, e⟩, ⟨l₁ ++ t, ⟨_, rfl⟩, by rw [← e, append_assoc]; exact ⟨_, rfl⟩⟩,
id ┴ ┴ └┘ └┘ └─┘ ┴ └──────────┘ └─┘
src └┘ └─┘ └────┘ └┘└──────────┘┴ └────┘ └─┘└─┘┴
typ ┴ ┴ └┘ └┘ └─┘ └────┘┴└┘└──────────┘┴ └────┘ └─┘└─┘┴
doc └────┘ └┘ ┴ └────┘ └─┘ ┴
txt └────┘ └┘ ┴ └────┘ └─┘ ┴
par └────┘ └┘ ┴ └────┘ └─┘ ┴
pid └──┘ └┘ ┴ ┴ └─┘ ┴
st └──────┘└────────────┘┴└──────────────┘
2238 λ⟨._, ⟨t, rfl⟩, ⟨s, e⟩⟩, ⟨s, t, by rw append_assoc; exact e⟩⟩
id ┴ ┴ └─┘ ┴ └──────────┘ ┴
src └─┘ └─┘└──────────┘ └────┘
typ ┴ ┴ └─┘ ┴ └─┘└──────────┘ └────┘┴
doc └─┘ └────┘
txt └─┘ └────┘
par └─┘ └────┘
pid ┴ ┴
st └───────────────────────┘
2239
2240 theorem eq_of_infix_of_length_eq {l₁ l₂ : list α} (s : l₁ <:+: l₂) : length l₁ = length l₂ → l₁ = l₂ :=
id └──┘ ┴ └┘ └──┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └──┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └──┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
doc └──┘
2241 eq_of_sublist_of_length_eq $ sublist_of_infix s
id └────────────────────────┘ └──────────────┘ ┴
src └────────────────────────┘ └──────────────┘
typ └────────────────────────┘ └──────────────┘ ┴
2242
2243 theorem eq_of_prefix_of_length_eq {l₁ l₂ : list α} (s : l₁ <+: l₂) : length l₁ = length l₂ → l₁ = l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
doc └─┘
2244 eq_of_sublist_of_length_eq $ sublist_of_prefix s
id └────────────────────────┘ └───────────────┘ ┴
src └────────────────────────┘ └───────────────┘
typ └────────────────────────┘ └───────────────┘ ┴
2245
2246 theorem eq_of_suffix_of_length_eq {l₁ l₂ : list α} (s : l₁ <:+ l₂) : length l₁ = length l₂ → l₁ = l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ └────┘ ┴ └────┘ ┴
typ └──┘ ┴ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ ┴ └┘
doc └─┘
2247 eq_of_sublist_of_length_eq $ sublist_of_suffix s
id └────────────────────────┘ └───────────────┘ ┴
src └────────────────────────┘ └───────────────┘
typ └────────────────────────┘ └───────────────┘ ┴
2248
2249 theorem prefix_of_prefix_length_le : ∀ {l₁ l₂ l₃ : list α},
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
2250 l₁ <+: l₃ → l₂ <+: l₃ → length l₁ ≤ length l₂ → l₁ <+: l₂
id └┘ └─┘ └┘ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ └─┘ └┘
src └─┘ └─┘ └────┘ ┴ └────┘ └─┘
typ └┘ └─┘ └┘ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ └─┘ └┘
doc └─┘ └─┘ └─┘
2251 | [] l₂ l₃ h₁ h₂ _ := nil_prefix _
id └┘ └────────┘
src └┘ └────────┘
typ └┘ └────────┘
2252 | (a::l₁) (b::l₂) _ ⟨r₁, rfl⟩ ⟨r₂, e⟩ ll := begin
id └┘ └┘ └─┘
src └┘ └┘ └─┘
typ └┘ └┘ └─┘
st └─────
2253 injection e with _ e', subst b,
id ┴ ┴
src └────────┘ └────────┘ └────┘
typ └────────┘┴└────────┘ └────┘┴
doc └────────┘ └────────┘ └────┘
txt └────────┘ └────────┘ └────┘
par └────────┘ └────────┘ └────┘
pid ┴ └────────┘ ┴
st ──────────────────────┘└───────┘└─
2254 rcases prefix_of_prefix_length_le ⟨_, rfl⟩ ⟨_, e'⟩
id └────────────────────────┘ └─┘ └┘
src └─────┘ ┴ └─┘└─┘└┘ └─┘ └─
typ └─────┘└────────────────────────┘┴ └─┘└─┘└┘ └─┘└┘└─
doc └─────┘ ┴ └─┘ └┘ └─┘ └─
txt └─────┘ ┴ └─┘ └┘ └─┘ └─
par └─────┘ ┴ └─┘ └┘ └─┘ └─
pid ┴ ┴ └─┘ └┘ └─┘ └─
st ─────────────────────────────────────────────────────
2255 (le_of_succ_le_succ ll) with ⟨r₃, rfl⟩,
id └────────────────┘ └┘
src ───┘ └────────────────┘┴ └──────────────┘
typ ───┘ └────────────────┘┴└┘└──────────────┘
doc ───┘ ┴ └──────────────┘
txt ───┘ ┴ └──────────────┘
par ───┘ ┴ └──────────────┘
pid ───┘ ┴ └──────────────┘
st ─────────────────────────────────────────┘└─
2256 exact ⟨r₃, rfl⟩
id └┘ └─┘
src └────┘ └┘└─┘└┘
typ └────┘ └┘└┘└─┘└┘
doc └────┘ └┘ └┘
txt └────┘ └┘ └┘
par └────┘ └┘ └┘
pid ┴ └┘ ┴┴
st ─────────────────┘
2257 end
st └─┘
2258
2259 theorem prefix_or_prefix_of_prefix {l₁ l₂ l₃ : list α}
id └──┘ ┴
src └──┘
typ └──┘ ┴
2260 (h₁ : l₁ <+: l₃) (h₂ : l₂ <+: l₃) : l₁ <+: l₂ ∨ l₂ <+: l₁ :=
id └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘ ┴ └┘ └─┘ └┘
src └─┘ └─┘ └─┘ ┴ └─┘
typ └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘ ┴ └┘ └─┘ └┘
doc └─┘ └─┘ └─┘ └─┘
2261 (le_total (length l₁) (length l₂)).imp
id └──────┘ └────┘ └┘ └────┘ └┘ └─┘
src └──────┘ └────┘ └────┘ └─┘
typ └──────┘ └────┘ └┘ └────┘ └┘ └─┘
2262 (prefix_of_prefix_length_le h₁ h₂)
id └────────────────────────┘ └┘ └┘
src └────────────────────────┘
typ └────────────────────────┘ └┘ └┘
2263 (prefix_of_prefix_length_le h₂ h₁)
id └────────────────────────┘ └┘ └┘
src └────────────────────────┘
typ └────────────────────────┘ └┘ └┘
2264
2265 theorem suffix_of_suffix_length_le {l₁ l₂ l₃ : list α}
id └──┘ ┴
src └──┘
typ └──┘ ┴
2266 (h₁ : l₁ <:+ l₃) (h₂ : l₂ <:+ l₃) (ll : length l₁ ≤ length l₂) : l₁ <:+ l₂ :=
id └┘ └─┘ └┘ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ └─┘ └┘
src └─┘ └─┘ └────┘ ┴ └────┘ └─┘
typ └┘ └─┘ └┘ └┘ └─┘ └┘ └────┘ └┘ ┴ └────┘ └┘ └┘ └─┘ └┘
doc └─┘ └─┘ └─┘
2267 reverse_prefix.1 $ prefix_of_prefix_length_le
id └────────────┘┴ └────────────────────────┘
src └────────────┘┴ └────────────────────────┘
typ └────────────┘┴ └────────────────────────┘
2268 (reverse_prefix.2 h₁) (reverse_prefix.2 h₂) (by simp [ll])
id └────────────┘┴ └┘ └────────────┘┴ └┘ └┘
src └────────────┘┴ └────────────┘┴ └────┘ ┴
typ └────────────┘┴ └┘ └────────────┘┴ └┘ └────┘└┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st └────────┘
2269
2270 theorem suffix_or_suffix_of_suffix {l₁ l₂ l₃ : list α}
id └──┘ ┴
src └──┘
typ └──┘ ┴
2271 (h₁ : l₁ <:+ l₃) (h₂ : l₂ <:+ l₃) : l₁ <:+ l₂ ∨ l₂ <:+ l₁ :=
id └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘ ┴ └┘ └─┘ └┘
src └─┘ └─┘ └─┘ ┴ └─┘
typ └┘ └─┘ └┘ └┘ └─┘ └┘ └┘ └─┘ └┘ ┴ └┘ └─┘ └┘
doc └─┘ └─┘ └─┘ └─┘
2272 (prefix_or_prefix_of_prefix (reverse_prefix.2 h₁) (reverse_prefix.2 h₂)).imp
id └────────────────────────┘ └────────────┘┴ └┘ └────────────┘┴ └┘ └─┘
src └────────────────────────┘ └────────────┘┴ └────────────┘┴ └─┘
typ └────────────────────────┘ └────────────┘┴ └┘ └────────────┘┴ └┘ └─┘
2273 reverse_prefix.1 reverse_prefix.1
id └────────────┘┴ └────────────┘┴
src └────────────┘┴ └────────────┘┴
typ └────────────┘┴ └────────────┘┴
2274
2275 theorem infix_of_mem_join : ∀ {L : list (list α)} {l}, l ∈ L → l <:+: join L
id ┴ └──┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └──┘ ┴
src └──┘ └──┘ ┴ └──┘ └──┘
typ ┴ └──┘ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ └──┘ ┴
doc └──┘
2276 | (_ :: L) l (or.inl rfl) := infix_append [] _ _
id └┘ └────┘ └─┘ └──────────┘ └┘
src └┘ └────┘ └─┘ └──────────┘ └┘
typ └┘ └────┘ └─┘ └──────────┘ └┘
2277 | (l' :: L) l (or.inr h) :=
id └┘ └────┘ ┴
src └┘ └────┘
typ └┘ └────┘ ┴
2278 is_infix.trans (infix_of_mem_join h) $ infix_of_suffix $ suffix_append _ _
id └────────────┘ └───────────────┘ └─────────────┘ └───────────┘
src └────────────┘ └─────────────┘ └───────────┘
typ └────────────┘ └───────────────┘ └─────────────┘ └───────────┘
2279
2280 theorem prefix_append_left_inj {l₁ l₂ : list α} (l) : l ++ l₁ <+: l ++ l₂ ↔ l₁ <+: l₂ :=
id └──┘ ┴ ┴ └┘ └┘ └─┘ ┴ └┘ └┘ ┴ └┘ └─┘ └┘
src └──┘ └┘ └─┘ └┘ ┴ └─┘
typ └──┘ ┴ ┴ └┘ └┘ └─┘ ┴ └┘ └┘ ┴ └┘ └─┘ └┘
doc └─┘ └─┘
2281 exists_congr $ λ r, by rw [append_assoc, append_left_inj]
id └──────────┘ ┴ └──────────┘ └─────────────┘
src └──────────┘ └──┘└──────────┘└┘└─────────────┘└─
typ └──────────┘ ┴ └──┘└──────────┘└┘└─────────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └───────────────┘└───────────────┘┴└
2282
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2283 theorem prefix_cons_inj {l₁ l₂ : list α} (a) : a :: l₁ <+: a :: l₂ ↔ l₁ <+: l₂ :=
id └──┘ ┴ ┴ └┘ └┘ └─┘ ┴ └┘ └┘ ┴ └┘ └─┘ └┘
src └──┘ └┘ └─┘ └┘ ┴ └─┘
typ └──┘ ┴ ┴ └┘ └┘ └─┘ ┴ └┘ └┘ ┴ └┘ └─┘ └┘
doc └─┘ └─┘
2284 prefix_append_left_inj [a]
id └────────────────────┘ ┴┴┴
src └────────────────────┘ ┴ ┴
typ └────────────────────┘ ┴┴┴
2285
2286 theorem take_prefix (n) (l : list α) : take n l <+: l := ⟨_, take_append_drop _ _⟩
id └──┘ ┴ └──┘ ┴ ┴ └─┘ ┴ └──────────────┘
src └──┘ └──┘ └─┘ └──────────────┘
typ └──┘ ┴ └──┘ ┴ ┴ └─┘ ┴ └──────────────┘
doc └─┘
2287
2288 theorem drop_suffix (n) (l : list α) : drop n l <:+ l := ⟨_, take_append_drop _ _⟩
id └──┘ ┴ └──┘ ┴ ┴ └─┘ ┴ └──────────────┘
src └──┘ └──┘ └─┘ └──────────────┘
typ └──┘ ┴ └──┘ ┴ ┴ └─┘ ┴ └──────────────┘
doc └─┘
2289
2290 theorem prefix_iff_eq_append {l₁ l₂ : list α} : l₁ <+: l₂ ↔ l₁ ++ drop (length l₁) l₂ = l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ ┴ └┘ └┘ └──┘ └────┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ ┴ └┘ └──┘ └────┘ ┴
typ └──┘ ┴ └┘ └─┘ └┘ ┴ └┘ └┘ └──┘ └────┘ └┘ └┘ ┴ └┘
doc └─┘
2291 ⟨by rintros ⟨r, rfl⟩; rw drop_left, λ e, ⟨_, e⟩⟩
id └───────┘ ┴ ┴
src └──────────────┘ └─┘└───────┘
typ └──────────────┘ └─┘└───────┘ ┴ ┴
doc └──────────────┘ └─┘
txt └──────────────┘ └─┘
par └──────────────┘ └─┘
pid └───────┘ ┴
st └────────────────────┘└───────┘
2292
2293 theorem suffix_iff_eq_append {l₁ l₂ : list α} : l₁ <:+ l₂ ↔ take (length l₂ - length l₁) l₂ ++ l₁ = l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ ┴ └──┘ └────┘ └┘ ┴ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ ┴ └──┘ └────┘ ┴ └────┘ └┘ ┴
typ └──┘ ┴ └┘ └─┘ └┘ ┴ └──┘ └────┘ └┘ ┴ └────┘ └┘ └┘ └┘ └┘ ┴ └┘
doc └─┘
2294 ⟨by rintros ⟨r, rfl⟩; simp only [length_append, nat.add_sub_cancel, take_left], λ e, ⟨_, e⟩⟩
id └───────────┘ └────────────────┘ └───────┘ ┴ ┴
src └──────────────┘ └─────────┘└───────────┘└┘└────────────────┘└┘└───────┘┴
typ └──────────────┘ └─────────┘└───────────┘└┘└────────────────┘└┘└───────┘┴ ┴ ┴
doc └──────────────┘ └─────────┘ └┘ └┘ ┴
txt └──────────────┘ └─────────┘ └┘ └┘ ┴
par └──────────────┘ └─────────┘ └┘ └┘ ┴
pid └───────┘ ┴└──┘└┘ └┘ └┘ ┴
st └─────────────────────────────────────────────────────────────────────────┘
2295
2296 theorem prefix_iff_eq_take {l₁ l₂ : list α} : l₁ <+: l₂ ↔ l₁ = take (length l₁) l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ ┴ └┘ ┴ └──┘ └────┘ └┘ └┘
src └──┘ └─┘ ┴ ┴ └──┘ └────┘
typ └──┘ ┴ └┘ └─┘ └┘ ┴ └┘ ┴ └──┘ └────┘ └┘ └┘
doc └─┘
2297 ⟨λ h, append_right_cancel $
id ┴ └─────────────────┘
src └─────────────────┘
typ ┴ └─────────────────┘
2298 (prefix_iff_eq_append.1 h).trans (take_append_drop _ _).symm,
id └──────────────────┘┴ ┴ └───┘ └──────────────┘ └──┘
src └──────────────────┘┴ └───┘ └──────────────┘ └──┘
typ └──────────────────┘┴ ┴ └───┘ └──────────────┘ └──┘
2299 λ e, e.symm ▸ take_prefix _ _⟩
id ┴ ┴└───┘ ┴ └─────────┘
src └───┘ ┴ └─────────┘
typ ┴ ┴└───┘ ┴ └─────────┘
2300
2301 theorem suffix_iff_eq_drop {l₁ l₂ : list α} : l₁ <:+ l₂ ↔ l₁ = drop (length l₂ - length l₁) l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ ┴ └┘ ┴ └──┘ └────┘ └┘ ┴ └────┘ └┘ └┘
src └──┘ └─┘ ┴ ┴ └──┘ └────┘ ┴ └────┘
typ └──┘ ┴ └┘ └─┘ └┘ ┴ └┘ ┴ └──┘ └────┘ └┘ ┴ └────┘ └┘ └┘
doc └─┘
2302 ⟨λ h, append_left_cancel $
id ┴ └────────────────┘
src └────────────────┘
typ ┴ └────────────────┘
2303 (suffix_iff_eq_append.1 h).trans (take_append_drop _ _).symm,
id └──────────────────┘┴ ┴ └───┘ └──────────────┘ └──┘
src └──────────────────┘┴ └───┘ └──────────────┘ └──┘
typ └──────────────────┘┴ ┴ └───┘ └──────────────┘ └──┘
2304 λ e, e.symm ▸ drop_suffix _ _⟩
id ┴ ┴└───┘ ┴ └─────────┘
src └───┘ ┴ └─────────┘
typ ┴ ┴└───┘ ┴ └─────────┘
2305
2306 instance decidable_prefix [decidable_eq α] : ∀ (l₁ l₂ : list α), decidable (l₁ <+: l₂)
id └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └─┘ └┘
src └──────────┘ └──┘ └───────┘ └─┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └─┘ └┘
doc └─┘
2307 | [] l₂ := is_true ⟨l₂, rfl⟩
id └┘ └┘ └─────┘ └─┘
src └┘ └─────┘ └─┘
typ └┘ └┘ └─────┘ └─┘
2308 | (a::l₁) [] := is_false $ λ ⟨t, te⟩, list.no_confusion te
id └┘ └┘ └──────┘ ┴ └┘ └───────────────┘
src └┘ └┘ └──────┘ └───────────────┘
typ └┘ └┘ └──────┘ ┴ └┘ └───────────────┘
2309 | (a::l₁) (b::l₂) :=
id ┴└┘└┘ ┴└┘└┘
src └┘ └┘
typ ┴└┘└┘ ┴└┘└┘
2310 if h : a = b then
id └┘ ┴
src └┘ ┴
typ └┘ ┴
2311 @decidable_of_iff _ _ (by rw [← h, prefix_cons_inj])
id └──────────────┘ ┴ └─────────────┘
src └──────────────┘ └────┘ └┘└─────────────┘┴
typ └──────────────┘ └────┘┴└┘└─────────────┘┴
doc └────┘ └┘ ┴
txt └────┘ └┘ ┴
par └────┘ └┘ ┴
pid └──┘ └┘ ┴
st └──────┘└───────────────┘┴
2312 (decidable_prefix l₁ l₂)
id └──────────────┘
typ └──────────────┘
2313 else
2314 is_false $ λ ⟨t, te⟩, h $ by injection te
id └──────┘ ┴ ┴ ┴ └┘
src └──────┘ └────────┘ └
typ └──────┘ ┴ ┴ ┴ └────────┘└┘└
doc └────────┘ └
txt └────────┘ └
par └────────┘ └
pid ┴ └
st └─────────────
2315
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
2316 -- Alternatively, use mem_tails
src ───────────────────────────────┘
typ ───────────────────────────────┘
doc ───────────────────────────────┘
txt ───────────────────────────────┘
par ───────────────────────────────┘
pid ───────────────────────────────┘
st ───────────────────────────────┘
2317 instance decidable_suffix [decidable_eq α] : ∀ (l₁ l₂ : list α), decidable (l₁ <:+ l₂)
id └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └─┘ └┘
src └──────────┘ └──┘ └───────┘ └─┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └─┘ └┘
doc └─┘
2318 | [] l₂ := is_true ⟨l₂, append_nil _⟩
id └┘ └┘ └─────┘ └────────┘
src └┘ └─────┘ └────────┘
typ └┘ └┘ └─────┘ └────────┘
2319 | (a::l₁) [] := is_false $ mt (length_le_of_sublist ∘ sublist_of_suffix) dec_trivial
id └┘ └┘ └──────┘ └┘ └──────────────────┘ ┴ └───────────────┘ └─────────┘
src └┘ └┘ └──────┘ └┘ └──────────────────┘ ┴ └───────────────┘ └─────────┘
typ └┘ └┘ └──────┘ └┘ └──────────────────┘ ┴ └───────────────┘ └─────────┘
doc └─────────┘
2320 | l₁ l₂ := let len1 := length l₁, len2 := length l₂ in
id └┘ └┘ └──┘ └────┘ └──┘ └────┘
src └────┘ └────┘
typ └┘ └┘ └──┘ └────┘ └──┘ └────┘
2321 if hl : len1 ≤ len2 then
id └┘ └──┘ ┴ └──┘
src └┘ ┴
typ └┘ └──┘ ┴ └──┘
2322 decidable_of_iff' (l₁ = drop (len2-len1) l₂) suffix_iff_eq_drop
id └───────────────┘ ┴ └──┘ └──┘┴└──┘ └────────────────┘
src └───────────────┘ ┴ └──┘ ┴ └────────────────┘
typ └───────────────┘ ┴ └──┘ └──┘┴└──┘ └────────────────┘
2323 else is_false $ λ h, hl $ length_le_of_sublist $ sublist_of_suffix h
id └──────┘ ┴ ┴ └┘ └──────────────────┘ └───────────────┘ ┴
src └──────┘ └──────────────────┘ └───────────────┘
typ └──────┘ ┴ ┴ └┘ └──────────────────┘ └───────────────┘ ┴
2324
2325 @[simp] theorem mem_inits : ∀ (s t : list α), s ∈ inits t ↔ s <+: t
id ┴ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘ ┴
src └──┘ ┴ └───┘ ┴ └─┘
typ ┴ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘ ┴
doc └──┘ └───┘ └─┘
2326 | s [] := suffices s = nil ↔ s <+: nil, by simpa only [inits, mem_singleton],
id ┴ └┘ ┴ └─┘ ┴ └─┘ └─┘ └───┘ └───────────┘
src └┘ ┴ └─┘ ┴ └─┘ └─┘ └──────────┘└───┘└┘└───────────┘┴
typ ┴ └┘ ┴ └─┘ ┴ └─┘ └─┘ └──────────┘└───┘└┘└───────────┘┴
doc └─┘ └──────────┘└───┘└┘ ┴
txt └──────────┘ └┘ ┴
par └──────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st └────────────────────────────────┘
2327 ⟨λh, h.symm ▸ prefix_refl [], eq_nil_of_prefix_nil⟩
id ┴ ┴└───┘ ┴ └─────────┘ └┘ └──────────────────┘
src └───┘ ┴ └─────────┘ └┘ └──────────────────┘
typ ┴ ┴└───┘ ┴ └─────────┘ └┘ └──────────────────┘
2328 | s (a::t) :=
id ┴ ┴└┘┴
src └┘
typ ┴ ┴└┘┴
2329 suffices (s = nil ∨ ∃ l ∈ inits t, a :: l = s) ↔ s <+: a :: t, by simpa,
id ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ └┘ ┴ ┴ ┴ └─┘ └┘
src ┴ └─┘ ┴ ┴ └───┘ ┴ └┘ ┴ ┴ └─┘ └┘ └───┘
typ ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ └┘ ┴ ┴ ┴ └─┘ └┘ └───┘
doc └───┘ └─┘ └───┘
txt └───┘
par └───┘
st └────┘
2330 ⟨λo, match s, o with
id ┴ ┴
typ ┴ ┴
2331 | ._, or.inl rfl := ⟨_, rfl⟩
id └────┘ └─┘ └─┘
src └────┘ └─┘ └─┘
typ └────┘ └─┘ └─┘
2332 | s, or.inr ⟨r, hr, hs⟩ := let ⟨s, ht⟩ := (mem_inits _ _).1 hr in
id └────┘ └┘ └─┘ └───────┘ ┴
src └────┘ ┴
typ └────┘ └┘ └─┘ └───────┘ ┴
2333 by rw [← hs, ← ht]; exact ⟨s, rfl⟩
id └┘ └┘ ┴ └─┘
src └────┘ └──┘ ┴ └────┘ └┘└─┘└─
typ └────┘└┘└──┘└┘┴ └────┘ ┴└┘└─┘└─
doc └────┘ └──┘ ┴ └────┘ └┘ └─
txt └────┘ └──┘ ┴ └────┘ └┘ └─
par └────┘ └──┘ ┴ └────┘ └┘ └─
pid └──┘ └──┘ ┴ ┴ └┘ ┴└
st └───────┘└────┘┴└────────────────
2334 end, λmi, match s, mi with
id └┘ └┘
src ─┘
typ ─┘ └┘ └┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
2335 | [], ⟨._, rfl⟩ := or.inl rfl
id └┘ └─┘ └────┘ └─┘
src └┘ └─┘ └────┘ └─┘
typ └┘ └─┘ └────┘ └─┘
2336 | (b::s), ⟨r, hr⟩ := list.no_confusion hr $ λba (st : s++r = t), or.inr $
id └┘┴ ┴ └┘ └───────────────┘ └┘ └┘ ┴ └────┘
src └┘ └───────────────┘ └┘ ┴ └────┘
typ └┘┴ ┴ └┘ └───────────────┘ └┘ └┘ ┴ └────┘
2337 by rw ba; exact ⟨_, (mem_inits _ _).2 ⟨_, st⟩, rfl⟩
id └┘ └───────┘ └┘ └─┘
src └─┘ └────┘ └─┘ └──────┘ └─┘ └─┘└─┘└─
typ └─┘└┘ └────┘ └─┘ └───────┘└──────┘ └─┘└┘└─┘└─┘└─
doc └─┘ └────┘ └─┘ └──────┘ └─┘ └─┘ └─
txt └─┘ └────┘ └─┘ └──────┘ └─┘ └─┘ └─
par └─┘ └────┘ └─┘ └──────┘ └─┘ └─┘ └─
pid ┴ ┴ └─┘ └──────┘ └─┘ └─┘ ┴└
st └─────────────────────────────────────────────────
2338 end⟩
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
2339
2340 @[simp] theorem mem_tails : ∀ (s t : list α), s ∈ tails t ↔ s <:+ t
id ┴ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘ ┴
src └──┘ ┴ └───┘ ┴ └─┘
typ ┴ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘ ┴
doc └──┘ └───┘ └─┘
2341 | s [] := by simp only [tails, mem_singleton]; exact ⟨λh, by rw h; exact suffix_refl [], eq_nil_of_suffix_nil⟩
id └┘ └───┘ └───────────┘ ┴ └──────────────────┘
src └┘ └─────────┘└───┘└┘└───────────┘┴ └────┘ └─┘ ┴└─┘ └──────┘ ┴ └┘└──────────────────┘└┘
typ └┘ └─────────┘└───┘└┘└───────────┘┴ └────┘ └─┘ ┴└─┘┴└──────┘ ┴ └┘└──────────────────┘└┘
doc └─────────┘└───┘└┘ ┴ └────┘ └─┘ ┴└─┘ └──────┘ ┴ └┘ └┘
txt └─────────┘ └┘ ┴ └────┘ └─┘ ┴└─┘ └──────┘ ┴ └┘ └┘
par └─────────┘ └┘ ┴ └────┘ └─┘ ┴└─┘ └──────┘ ┴ └┘ └┘
pid ┴└──┘└┘ └┘ ┴ ┴ └─┘ └──┘ └──────┘ ┴ └┘ ┴┴
st └──────────────────────────────────────────────┘└─────────────────────────┘└──────────────────────┘
2342 | s (a::t) := by simp only [tails, mem_cons_iff, mem_tails s t]; exact show s = a :: t ∨ s <:+ t ↔ s <:+ a :: t, from
id └┘ └───┘ └──────────┘ └───────┘ ┴ ┴ ┴ └─┘ ┴
src └┘ └─────────┘└───┘└┘└──────────┘└┘ ┴ ┴ ┴ └────┘ ┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴└─┘┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────
typ └┘ └─────────┘└───┘└┘└──────────┘└┘└───────┘┴┴┴┴┴ └────┘ ┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴└─┘┴ ┴┴┴ ┴ ┴ ┴ ┴ └──────
doc └─────────┘└───┘└┘ └┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴└─┘┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────
txt └─────────┘ └┘ └┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────
par └─────────┘ └┘ └┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────
st └─────────────────────────────────────────────────────────────────────────────────────────────────────
2343 ⟨λo, match s, t, o with
src ─┘ └─┘ ┴ └┘ └┘ └─────
typ ─┘ └─┘ ┴ └┘ └┘ └─────
doc ─┘ └─┘ ┴ └┘ └┘ └─────
txt ─┘ └─┘ ┴ └┘ └┘ └─────
par ─┘ └─┘ ┴ └┘ └┘ └─────
pid ─┘ └─┘ ┴ └┘ └┘ └─────
st ──────────────────────────
2344 | ._, t, or.inl rfl := suffix_refl _
id └─────────┘
src ───┘ └┘ └┘ ┴ └──┘└─────────┘└──
typ ───┘ └┘ └┘ ┴ └──┘└─────────┘└──
doc ───┘ └┘ └┘ ┴ └──┘ └──
txt ───┘ └┘ └┘ ┴ └──┘ └──
par ───┘ └┘ └┘ ┴ └──┘ └──
pid ───┘ └┘ └┘ ┴ └──┘ └──
st ───────────────────────────────────────
2345 | s, ._, or.inr ⟨l, rfl⟩ := ⟨a::l, rfl⟩
id ┴ ┴
src ───┘ └┘ └┘ ┴ └┘ └───┘ └┘ └─
typ ───┘ └┘ └┘ ┴ ┴└┘ └───┘ ┴ └┘ └─
doc ───┘ └┘ └┘ ┴ └┘ └───┘ └┘ └─
txt ───┘ └┘ └┘ ┴ └┘ └───┘ └┘ └─
par ───┘ └┘ └┘ ┴ └┘ └───┘ └┘ └─
pid ───┘ └┘ └┘ ┴ └┘ └───┘ └┘ └─
st ──────────────────────────────────────────
2346 end, λe, match s, t, e with
id ┴ ┴
src ──────┘ └─┘ ┴ └┘ └┘ └─────
typ ──────┘ └─┘ ┴┴└┘┴└┘ └─────
doc ──────┘ └─┘ ┴ └┘ └┘ └─────
txt ──────┘ └─┘ ┴ └┘ └┘ └─────
par ──────┘ └─┘ ┴ └┘ └┘ └─────
pid ──────┘ └─┘ ┴ └┘ └┘ └─────
st ──────────────────────────────
2347 | ._, t, ⟨[], rfl⟩ := or.inl rfl
id └────┘ └─┘
src ───┘ └┘ └┘ └┘ └───┘└────┘┴└─┘└
typ ───┘ └┘ └┘ └┘ └───┘└────┘┴└─┘└
doc ───┘ └┘ └┘ └┘ └───┘ ┴ └
txt ───┘ └┘ └┘ └┘ └───┘ ┴ └
par ───┘ └┘ └┘ └┘ └───┘ ┴ └
pid ───┘ └┘ └┘ └┘ └───┘ ┴ └
st ───────────────────────────────────
2348 | s, t, ⟨b::l, he⟩ := list.no_confusion he (λab lt, or.inr ⟨l, lt⟩)
id ┴ └┘ └───────────────┘ └────┘
src ───┘ └┘ └┘ └┘ └───┘└───────────────┘┴ ┴ └─────┘└────┘┴ └┘ └──
typ ───┘ └┘ └┘ ┴└┘└┘└───┘└───────────────┘┴ ┴ └─────┘└────┘┴ └┘ └──
doc ───┘ └┘ └┘ └┘ └───┘ ┴ ┴ └─────┘ ┴ └┘ └──
txt ───┘ └┘ └┘ └┘ └───┘ ┴ ┴ └─────┘ ┴ └┘ └──
par ───┘ └┘ └┘ └┘ └───┘ ┴ ┴ └─────┘ ┴ └┘ └──
pid ───┘ └┘ └┘ └┘ └───┘ ┴ ┴ └─────┘ ┴ └┘ └──
st ──────────────────────────────────────────────────────────────────────
2349 end⟩
src ───────
typ ───────
doc ───────
txt ───────
par ───────
pid ─────┘└
st ───────
2350
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2351 instance decidable_infix [decidable_eq α] : ∀ (l₁ l₂ : list α), decidable (l₁ <:+: l₂)
id └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └──┘ └┘
src └──────────┘ └──┘ └───────┘ └──┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └───────┘ └┘ └──┘ └┘
doc └──┘
2352 | [] l₂ := is_true ⟨[], l₂, rfl⟩
id └┘ └┘ └─────┘ └┘ └─┘
src └┘ └─────┘ └┘ └─┘
typ └┘ └┘ └─────┘ └┘ └─┘
2353 | (a::l₁) [] := is_false $ λ⟨s, t, te⟩, absurd te $ append_ne_nil_of_ne_nil_left _ _ $
id └┘ └┘ └──────┘ ┴ └┘ └────┘ └──────────────────────────┘
src └┘ └┘ └──────┘ └────┘ └──────────────────────────┘
typ └┘ └┘ └──────┘ ┴ └┘ └────┘ └──────────────────────────┘
2354 append_ne_nil_of_ne_nil_right _ _ $ λh, list.no_confusion h
id └───────────────────────────┘ ┴ └───────────────┘ ┴
src └───────────────────────────┘ └───────────────┘
typ └───────────────────────────┘ ┴ └───────────────┘ ┴
2355 | l₁ l₂ := decidable_of_decidable_of_iff (list.decidable_bex (λt, l₁ <+: t) (tails l₂)) $
id └┘ └┘ └───────────────────────────┘ └────────────────┘ ┴ └─┘ ┴ └───┘
src └───────────────────────────┘ └────────────────┘ └─┘ └───┘
typ └┘ └┘ └───────────────────────────┘ └────────────────┘ ┴ └─┘ ┴ └───┘
doc └─┘ └───┘
2356 by refine (exists_congr (λt, _)).trans (infix_iff_prefix_suffix _ _).symm;
id └──────────┘ └─────────────────────┘
src └─────┘ └──────────┘┴ └───────────┘ └─────────────────────┘└────────┘
typ └─────┘ └──────────┘┴ └───────────┘ └─────────────────────┘└────────┘
doc └─────┘ ┴ └───────────┘ └────────┘
txt └─────┘ ┴ └───────────┘ └────────┘
par └─────┘ ┴ └───────────┘ └────────┘
pid ┴ ┴ └───────────┘ └───────┘┴
st └────────────────────────────────────────────────────────────────────────
2357 exact ⟨λ⟨h1, h2⟩, ⟨h2, (mem_tails _ _).1 h1⟩, λ⟨h2, h1⟩, ⟨(mem_tails _ _).2 h1, h2⟩⟩
id └┘ └┘ └┘ └┘ └───────┘
src └────┘ ┴ └┘ └─┘ └┘ └──────┘ └─┘ ┴ └┘ └─┘ └───────┘└──────┘ └┘ └──
typ └────┘ ┴└┘└┘└┘└─┘ └┘ └──────┘ └─┘ ┴└┘└┘└┘└─┘ └───────┘└──────┘ └┘ └──
doc └────┘ ┴ └┘ └─┘ └┘ └──────┘ └─┘ ┴ └┘ └─┘ └──────┘ └┘ └──
txt └────┘ ┴ └┘ └─┘ └┘ └──────┘ └─┘ ┴ └┘ └─┘ └──────┘ └┘ └──
par └────┘ ┴ └┘ └─┘ └┘ └──────┘ └─┘ ┴ └┘ └─┘ └──────┘ └┘ └──
pid ┴ ┴ └┘ └─┘ └┘ └──────┘ └─┘ ┴ └┘ └─┘ └──────┘ └┘ └┘└
st ──────────────────────────────────────────────────────────────────────────────────────────
2358
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
2359 /- sublists -/
src ───────────────
typ ───────────────
doc ───────────────
txt ───────────────
par ───────────────
pid ───────────────
st ───────────────
2360
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2361 @[simp] theorem sublists'_nil : sublists' (@nil α) = [[]] := rfl
id └───────┘ └─┘ ┴ ┴ ┴└┘┴ └─┘
src └───────┘ └─┘ ┴ └──┘ └─┘
typ └───────┘ └─┘ ┴ ┴ ┴└┘┴ └─┘
doc └──┘ └───────┘
2362
2363 @[simp] theorem sublists'_singleton (a : α) : sublists' [a] = [[], [a]] := rfl
id ┴ └───────┘ ┴┴┴ ┴ ┴└┘┴ ┴┴└┘ └─┘
src └───────┘ ┴ ┴ ┴ └──┘ ┴ └┘ └─┘
typ ┴ └───────┘ ┴┴┴ ┴ ┴└┘┴ ┴┴└┘ └─┘
doc └──┘ └───────┘
2364
2365 theorem map_sublists'_aux (g : list β → list γ) (l : list α) (f r) :
id └──┘ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ └──┘ ┴
2366 map g (sublists'_aux l f r) = sublists'_aux l (g ∘ f) (map g r) :=
id └─┘ ┴ └───────────┘ ┴ ┴ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src └─┘ └───────────┘ ┴ └───────────┘ ┴ └─┘
typ └─┘ ┴ └───────────┘ ┴ ┴ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
2367 by induction l generalizing f r; [refl, simp only [*, sublists'_aux]]
id ┴ ┴ └───────────┘
src └────────┘ └───────────────┘ ┴└──┘ └────────────┘└───────────┘┴
typ └────────┘┴└───────────────┘ ┴└──┘ └────────────┘└───────────┘┴
doc └────────┘ └───────────────┘ └──┘ └────────────┘ ┴
txt └────────┘ └───────────────┘ └──┘ └────────────┘ ┴
par └────────┘ └───────────────┘ └──┘ └────────────┘ ┴
pid ┴ ┴└──────────────┘ ┴└──┘└───┘ ┴
st └─────────────────────────────────────────────────────────────────┘
2368
2369 theorem sublists'_aux_append (r' : list (list β)) (l : list α) (f r) :
id └──┘ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ └──┘ ┴ └──┘ ┴
2370 sublists'_aux l f (r ++ r') = sublists'_aux l f r ++ r' :=
id └───────────┘ ┴ ┴ ┴ └┘ └┘ ┴ └───────────┘ ┴ ┴ ┴ └┘ └┘
src └───────────┘ └┘ ┴ └───────────┘ └┘
typ └───────────┘ ┴ ┴ ┴ └┘ └┘ ┴ └───────────┘ ┴ ┴ ┴ └┘ └┘
2371 by induction l generalizing f r; [refl, simp only [*, sublists'_aux]]
id ┴ ┴ └───────────┘
src └────────┘ └───────────────┘ ┴└──┘ └────────────┘└───────────┘┴
typ └────────┘┴└───────────────┘ ┴└──┘ └────────────┘└───────────┘┴
doc └────────┘ └───────────────┘ └──┘ └────────────┘ ┴
txt └────────┘ └───────────────┘ └──┘ └────────────┘ ┴
par └────────┘ └───────────────┘ └──┘ └────────────┘ ┴
pid ┴ ┴└──────────────┘ ┴└──┘└───┘ ┴
st └─────────────────────────────────────────────────────────────────┘
2372
2373 theorem sublists'_aux_eq_sublists' (l f r) :
2374 @sublists'_aux α β l f r = map f (sublists' l) ++ r :=
id └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └───────┘ ┴ └┘ ┴
src └───────────┘ ┴ └─┘ └───────┘ └┘
typ └───────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └───────┘ ┴ └┘ ┴
doc └───────┘
2375 by rw [sublists', map_sublists'_aux, ← sublists'_aux_append]; refl
id └───────┘ └───────────────┘ └──────────────────┘
src └──┘└───────┘└┘└───────────────┘└──┘└──────────────────┘┴ └────
typ └──┘└───────┘└┘└───────────────┘└──┘└──────────────────┘┴ └────
doc └──┘└───────┘└┘ └──┘ ┴ └────
txt └──┘ └┘ └──┘ ┴ └────
par └──┘ └┘ └──┘ ┴ └────
pid └┘ └┘ └──┘ ┴ └
st └────────────┘└─────────────────┘└──────────────────────┘┴└──────
2376
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2377 @[simp] theorem sublists'_cons (a : α) (l : list α) :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
2378 sublists' (a :: l) = sublists' l ++ map (cons a) (sublists' l) :=
id └───────┘ ┴ └┘ ┴ ┴ └───────┘ ┴ └┘ └─┘ └──┘ ┴ └───────┘ ┴
src └───────┘ └┘ ┴ └───────┘ └┘ └─┘ └──┘ └───────┘
typ └───────┘ ┴ └┘ ┴ ┴ └───────┘ ┴ └┘ └─┘ └──┘ ┴ └───────┘ ┴
doc └───────┘ └───────┘ └───────┘
2379 by rw [sublists', sublists'_aux]; simp only [sublists'_aux_eq_sublists', map_id, append_nil]; refl
id └───────┘ └───────────┘ └────────────────────────┘ └────┘ └────────┘
src └──┘└───────┘└┘└───────────┘┴ └─────────┘└────────────────────────┘└┘└────┘└┘└────────┘┴ └────
typ └──┘└───────┘└┘└───────────┘┴ └─────────┘└────────────────────────┘└┘└────┘└┘└────────┘┴ └────
doc └──┘└───────┘└┘ ┴ └─────────┘ └┘ └┘ ┴ └────
txt └──┘ └┘ ┴ └─────────┘ └┘ └┘ ┴ └────
par └──┘ └┘ ┴ └─────────┘ └┘ └┘ ┴ └────
pid └┘ └┘ ┴ ┴└──┘└┘ └┘ └┘ ┴ └
st └────────────┘└─────────────┘┴└──────────────────────────────────────────────────────────────────
2380
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2381 @[simp] theorem mem_sublists' {s t : list α} : s ∈ sublists' t ↔ s <+ t :=
id └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ └┘ ┴
src └──┘ ┴ └───────┘ ┴ └┘
typ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ └┘ ┴
doc └──┘ └───────┘
2382 begin
st └─────
2383 induction t with a t IH generalizing s,
id ┴
src └────────┘ └─────────────────────────┘
typ └────────┘┴└─────────────────────────┘
doc └────────┘ └─────────────────────────┘
txt └────────┘ └─────────────────────────┘
par └────────┘ └─────────────────────────┘
pid ┴ ┴└─────────┘└─────────────┘
st ───────────────────────────────────────┘└─
2384 { simp only [sublists'_nil, mem_singleton],
id └───────────┘ └───────────┘
src └─────────┘└───────────┘└┘└───────────┘┴
typ └─────────┘└───────────┘└┘└───────────┘┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st ───┘└──────────────────────────────────────┘└─
2385 exact ⟨λ h, by rw h, eq_nil_of_sublist_nil⟩ },
id ┴ └───────────────────┘
src └────┘ └──┘ ┴└─┘ └┘└───────────────────┘└┘
typ └────┘ └──┘ ┴└─┘┴└┘└───────────────────┘└┘
doc └────┘ └──┘ ┴└─┘ └┘ └┘
txt └────┘ └──┘ ┴└─┘ └┘ └┘
par └────┘ └──┘ ┴└─┘ └┘ └┘
pid ┴ └──┘ └──┘ └┘ ┴┴
st ─────────────────┘└───┘└───────────────────────┘└┘└
2386 simp only [sublists'_cons, mem_append, IH, mem_map],
id └────────────┘ └────────┘ └─────┘
src └─────────┘└────────────┘└┘└────────┘└┘ └┘└─────┘┴
typ └─────────┘└────────────┘└┘└────────┘└┘└┘└┘└─────┘┴
doc └─────────┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ ┴
st ────────────────────────────────────────────────────┘└─
2387 split; intro h, rcases h with h | ⟨s, h, rfl⟩,
id ┴
src └───┘ └─────┘ └─────┘ └───────────────────┘
typ └───┘ └─────┘ └─────┘┴└───────────────────┘
doc └───┘ └─────┘ └─────┘ └───────────────────┘
txt └───┘ └─────┘ └─────┘ └───────────────────┘
par └───┘ └─────┘ └─────┘ └───────────────────┘
pid └┘ ┴ └───────────────────┘
st ───────────────┘└─────────────────────────────┘└─
2388 { exact sublist_cons_of_sublist _ h },
id └─────────────────────┘ ┴
src └────┘└─────────────────────┘└─┘ ┴
typ └────┘└─────────────────────┘└─┘┴┴
doc └────┘ └─┘ ┴
txt └────┘ └─┘ ┴
par └────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ───┘└────────────────────────────────┘└┘└
2389 { exact cons_sublist_cons _ h },
id └───────────────┘ ┴
src └────┘└───────────────┘└─┘ ┴
typ └────┘└───────────────┘└─┘┴┴
doc └────┘ └─┘ ┴
txt └────┘ └─┘ ┴
par └────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ───┘└──────────────────────────┘└┘└
2390 { cases h with _ _ _ h s _ _ h,
id ┴
src └────┘ └───────────────────┘
typ └────┘┴└───────────────────┘
doc └────┘ └───────────────────┘
txt └────┘ └───────────────────┘
par └────┘ └───────────────────┘
pid ┴ └───────────────────┘
st ───────────────────────────────┘└─
2391 { exact or.inl h },
id └────┘ ┴
src └────┘└────┘┴ ┴
typ └────┘└────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ─────┘└─────────────┘└┘└
2392 { exact or.inr ⟨s, h, rfl⟩ } }
id └────┘ ┴ ┴ └─┘
src └────┘└────┘┴ └┘ └┘└─┘└┘
typ └────┘└────┘┴ ┴└┘┴└┘└─┘└┘
doc └────┘ ┴ └┘ └┘ └┘
txt └────┘ ┴ └┘ └┘ └┘
par └────┘ ┴ └┘ └┘ └┘
pid ┴ ┴ └┘ └┘ ┴┴
st ──────────────────────────────┘└───
2393 end
st ──┘
2394
2395 @[simp] theorem length_sublists' : ∀ l : list α, length (sublists' l) = 2 ^ length l
id ┴ └──┘ ┴ └────┘ └───────┘ ┴ ┴ ┴ └────┘ ┴
src └──┘ └────┘ └───────┘ ┴ ┴ └────┘
typ ┴ └──┘ ┴ └────┘ └───────┘ ┴ ┴ ┴ └────┘ ┴
doc └──┘ └───────┘
2396 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2397 | (a::l) := by simp only [sublists'_cons, length_append, length_sublists' l, length_map,
id └┘ └────────────┘ └───────────┘ └──────────────┘ ┴ └────────┘
src └┘ └─────────┘└────────────┘└┘└───────────┘└┘ ┴ └┘└────────┘└─
typ └┘ └─────────┘└────────────┘└┘└───────────┘└┘└──────────────┘┴┴└┘└────────┘└─
doc └─────────┘ └┘ └┘ ┴ └┘ └─
txt └─────────┘ └┘ └┘ ┴ └┘ └─
par └─────────┘ └┘ └┘ ┴ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴ └┘ └─
st └──────────────────────────────────────────────────────────────────────────
2398 length, pow_succ, mul_succ, mul_zero, zero_add]
id └────┘ └──────┘ └──────┘ └──────┘ └──────┘
src ───┘└────┘└┘└──────┘└┘└──────┘└┘└──────┘└┘└──────┘└─
typ ───┘└────┘└┘└──────┘└┘└──────┘└┘└──────┘└┘└──────┘└─
doc ───┘ └┘ └┘ └┘ └┘ └─
txt ───┘ └┘ └┘ └┘ └┘ └─
par ───┘ └┘ └┘ └┘ └┘ └─
pid ───┘ └┘ └┘ └┘ └┘ ┴└
st ────────────────────────────────────────────────────
2399
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2400 @[simp] theorem sublists_nil : sublists (@nil α) = [[]] := rfl
id └──────┘ └─┘ ┴ ┴ ┴└┘┴ └─┘
src └──────┘ └─┘ ┴ └──┘ └─┘
typ └──────┘ └─┘ ┴ ┴ ┴└┘┴ └─┘
doc └──┘ └──────┘
2401
2402 @[simp] theorem sublists_singleton (a : α) : sublists [a] = [[], [a]] := rfl
id ┴ └──────┘ ┴┴┴ ┴ ┴└┘┴ ┴┴└┘ └─┘
src └──────┘ ┴ ┴ ┴ └──┘ ┴ └┘ └─┘
typ ┴ └──────┘ ┴┴┴ ┴ ┴└┘┴ ┴┴└┘ └─┘
doc └──┘ └──────┘
2403
2404 theorem sublists_aux₁_eq_sublists_aux : ∀ l (f : list α → list β),
id ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ ┴ └──┘ ┴
2405 sublists_aux₁ l f = sublists_aux l (λ ys r, f ys ++ r)
id └───────────┘ ┴ ┴ ┴ └──────────┘ ┴ └┘ ┴ ┴ └┘ └┘ ┴
src └───────────┘ ┴ └──────────┘ └┘
typ └───────────┘ ┴ ┴ ┴ └──────────┘ ┴ └┘ ┴ ┴ └┘ └┘ ┴
2406 | [] f := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2407 | (a::l) f := by rw [sublists_aux₁, sublists_aux]; simp only [*, append_assoc]
id └┘ └───────────┘ └──────────┘ └──────────┘
src └┘ └──┘└───────────┘└┘└──────────┘┴ └────────────┘└──────────┘└─
typ └┘ └──┘└───────────┘└┘└──────────┘┴ └────────────┘└──────────┘└─
doc └──┘ └┘ ┴ └────────────┘ └─
txt └──┘ └┘ ┴ └────────────┘ └─
par └──┘ └┘ ┴ └────────────┘ └─
pid └┘ └┘ ┴ ┴└──┘└───┘ ┴└
st └────────────────┘└────────────┘┴└─────────────────────────────
2408
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2409 theorem sublists_aux_cons_eq_sublists_aux₁ (l : list α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
2410 sublists_aux l cons = sublists_aux₁ l (λ x, [x]) :=
id └──────────┘ ┴ └──┘ ┴ └───────────┘ ┴ ┴ ┴┴┴
src └──────────┘ └──┘ ┴ └───────────┘ ┴ ┴
typ └──────────┘ ┴ └──┘ ┴ └───────────┘ ┴ ┴ ┴┴┴
2411 by rw [sublists_aux₁_eq_sublists_aux]; refl
id └───────────────────────────┘
src └──┘└───────────────────────────┘┴ └────
typ └──┘└───────────────────────────┘┴ └────
doc └──┘ ┴ └────
txt └──┘ ┴ └────
par └──┘ ┴ └────
pid └┘ ┴ └
st └────────────────────────────────┘┴└──────
2412
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2413 theorem sublists_aux_eq_foldr.aux {a : α} {l : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
2414 (IH₁ : ∀ (f : list α → list β → list β), sublists_aux l f = foldr f [] (sublists_aux l cons))
id └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴ └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
src └──┘ └──┘ └──┘ └──────────┘ ┴ └───┘ └┘ └──────────┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴ └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
2415 (IH₂ : ∀ (f : list α → list (list α) → list (list α)),
id └──┘ ┴ ┴ └──┘ └──┘ ┴ └──┘ └──┘ ┴
src └──┘ └──┘ └──┘ └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ └──┘ ┴ └──┘ └──┘ ┴
2416 sublists_aux l f = foldr f [] (sublists_aux l cons))
id └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
src └──────────┘ ┴ └───┘ └┘ └──────────┘ └──┘
typ └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
2417 (f : list α → list β → list β) : sublists_aux (a::l) f = foldr f [] (sublists_aux (a::l) cons) :=
id └──┘ ┴ └──┘ ┴ └──┘ ┴ └──────────┘ ┴└┘┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴└┘┴ └──┘
src └──┘ └──┘ └──┘ └──────────┘ └┘ ┴ └───┘ └┘ └──────────┘ └┘ └──┘
typ └──┘ ┴ └──┘ ┴ └──┘ ┴ └──────────┘ ┴└┘┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴└┘┴ └──┘
2418 begin
st └─────
2419 simp only [sublists_aux, foldr_cons], rw [IH₂, IH₁], congr' 1,
id └──────────┘ └────────┘ └─┘ └─┘
src └─────────┘└──────────┘└┘└────────┘┴ └──┘ └┘ ┴ └──────┘
typ └─────────┘└──────────┘└┘└────────┘┴ └──┘└─┘└┘└─┘┴ └──────┘
doc └─────────┘ └┘ ┴ └──┘ └┘ ┴ └──────┘
txt └─────────┘ └┘ ┴ └──┘ └┘ ┴ └──────┘
par └─────────┘ └┘ ┴ └──┘ └┘ ┴ └──────┘
pid ┴└──┘└┘ └┘ ┴ └┘ └┘ ┴ ┴┴
st ─────────────────────────────────────┘└───────┘└───┘└─────────┘└─
2420 induction sublists_aux l cons with _ _ ih, {refl},
id └──────────┘ ┴ └──┘
src └────────┘└──────────┘┴ ┴└──┘└──────────┘ └──┘
typ └────────┘└──────────┘┴┴┴└──┘└──────────┘ └──┘
doc └────────┘ ┴ ┴ └──────────┘ └──┘
txt └────────┘ ┴ ┴ └──────────┘ └──┘
par └────────┘ ┴ ┴ └──────────┘ └──┘
pid ┴ ┴ ┴ ┴└─────────┘
st ──────────────────────────────────────────┘└─────┘└┘└
2421 simp only [ih, foldr_cons]
id └┘ └────────┘
src └─────────┘ └┘└────────┘└┘
typ └─────────┘└┘└┘└────────┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st ────────────────────────────┘
2422 end
st └─┘
2423
2424 theorem sublists_aux_eq_foldr (l : list α) : ∀ (f : list α → list β → list β),
id └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴
2425 sublists_aux l f = foldr f [] (sublists_aux l cons) :=
id └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
src └──────────┘ ┴ └───┘ └┘ └──────────┘ └──┘
typ └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
2426 suffices _ ∧ ∀ f : list α → list (list α) → list (list α),
id ┴ └──┘ ┴ ┴ └──┘ └──┘ ┴ └──┘ └──┘ ┴
src ┴ └──┘ └──┘ └──┘ └──┘ └──┘
typ ┴ └──┘ ┴ ┴ └──┘ └──┘ ┴ └──┘ └──┘ ┴
2427 sublists_aux l f = foldr f [] (sublists_aux l cons),
id └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
src └──────────┘ ┴ └───┘ └┘ └──────────┘ └──┘
typ └──────────┘ ┴ ┴ ┴ └───┘ ┴ └┘ └──────────┘ ┴ └──┘
2428 from this.1,
id └──┘┴
src ┴
typ └──┘┴
2429 begin
st └─────
2430 induction l with a l IH, {split; intro; refl},
id ┴
src └────────┘ └──────────┘ └───┘ └───┘ └──┘
typ └────────┘┴└──────────┘ └───┘ └───┘ └──┘
doc └────────┘ └──────────┘ └───┘ └───┘ └──┘
txt └────────┘ └──────────┘ └───┘ └───┘ └──┘
par └────────┘ └──────────┘ └───┘ └───┘ └──┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└───────────────────┘└┘└
2431 exact ⟨sublists_aux_eq_foldr.aux IH.1 IH.2,
src └────┘ ┴ └─┘ └───
typ └────┘ ┴ └─┘ └───
doc └────┘ ┴ └─┘ └───
txt └────┘ ┴ └─┘ └───
par └────┘ ┴ └─┘ └───
pid ┴ ┴ └─┘ └───
st ──────────────────────────────────────────────
2432 sublists_aux_eq_foldr.aux IH.2 IH.2⟩
id └───────────────────────┘ └┘
src ────────┘└───────────────────────┘┴ └─┘ └──┘
typ ────────┘└───────────────────────┘┴ └─┘└┘└──┘
doc ────────┘ ┴ └─┘ └──┘
txt ────────┘ ┴ └─┘ └──┘
par ────────┘ ┴ └─┘ └──┘
pid ────────┘ ┴ └─┘ └─┘┴
st ─────────────────────────────────────────────┘
2433 end
st └─┘
2434
2435 theorem sublists_aux_cons_cons (l : list α) (a : α) :
id └──┘ ┴ ┴
src └──┘
typ └──┘ ┴ ┴
2436 sublists_aux (a::l) cons = [a] :: foldr (λys r, ys :: (a :: ys) :: r) [] (sublists_aux l cons) :=
id └──────────┘ ┴└┘┴ └──┘ ┴ ┴┴┴ └┘ └───┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘ └┘ ┴ └┘ └──────────┘ ┴ └──┘
src └──────────┘ └┘ └──┘ ┴ ┴ ┴ └┘ └───┘ └┘ └┘ └┘ └┘ └──────────┘ └──┘
typ └──────────┘ ┴└┘┴ └──┘ ┴ ┴┴┴ └┘ └───┘ └┘ ┴ └┘ └┘ ┴ └┘ └┘ └┘ ┴ └┘ └──────────┘ ┴ └──┘
2437 by rw [← sublists_aux_eq_foldr]; refl
id └───────────────────┘
src └────┘└───────────────────┘┴ └────
typ └────┘└───────────────────┘┴ └────
doc └────┘ ┴ └────
txt └────┘ ┴ └────
par └────┘ ┴ └────
pid └──┘ ┴ └
st └──────────────────────────┘┴└──────
2438
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2439 theorem sublists_aux₁_append : ∀ (l₁ l₂ : list α) (f : list α → list β),
id ┴ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴ ┴ └──┘ ┴
2440 sublists_aux₁ (l₁ ++ l₂) f = sublists_aux₁ l₁ f ++
id └───────────┘ └┘ └┘ └┘ ┴ ┴ └───────────┘ └┘ ┴ └┘
src └───────────┘ └┘ ┴ └───────────┘ └┘
typ └───────────┘ └┘ └┘ └┘ ┴ ┴ └───────────┘ └┘ ┴ └┘
2441 sublists_aux₁ l₂ (λ x, f x ++ sublists_aux₁ l₁ (f ∘ (++ x)))
id └───────────┘ └┘ ┴ ┴ ┴ └┘ └───────────┘ └┘ ┴ ┴ ┴ ┴
src └───────────┘ └┘ └───────────┘ ┴ ┴
typ └───────────┘ └┘ ┴ ┴ ┴ └┘ └───────────┘ └┘ ┴ ┴ ┴ ┴
2442 | [] l₂ f := by simp only [sublists_aux₁, nil_append, append_nil]
id └┘ └───────────┘ └────────┘ └────────┘
src └┘ └─────────┘└───────────┘└┘└────────┘└┘└────────┘└┘
typ └┘ └─────────┘└───────────┘└┘└────────┘└┘└────────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st └─────────────────────────────────────────────────┘
2443 | (a::l₁) l₂ f := by simp only [sublists_aux₁, cons_append, sublists_aux₁_append l₁, append_assoc]; refl
id └┘ └───────────┘ └─────────┘ └──────────────────┘ └┘ └──────────┘
src └┘ └─────────┘└───────────┘└┘└─────────┘└┘ ┴ └┘└──────────┘┴ └────
typ └┘ └─────────┘└───────────┘└┘└─────────┘└┘└──────────────────┘┴└┘└┘└──────────┘┴ └────
doc └─────────┘ └┘ └┘ ┴ └┘ ┴ └────
txt └─────────┘ └┘ └┘ ┴ └┘ ┴ └────
par └─────────┘ └┘ └┘ ┴ └┘ ┴ └────
pid ┴└──┘└┘ └┘ └┘ ┴ └┘ ┴ └
st └────────────────────────────────────────────────────────────────────────────────────
2444
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2445 theorem sublists_aux₁_concat (l : list α) (a : α) (f : list α → list β) :
id └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ └──┘ ┴
2446 sublists_aux₁ (l ++ [a]) f = sublists_aux₁ l f ++
id └───────────┘ ┴ └┘ ┴┴┴ ┴ ┴ └───────────┘ ┴ ┴ └┘
src └───────────┘ └┘ ┴ ┴ ┴ └───────────┘ └┘
typ └───────────┘ ┴ └┘ ┴┴┴ ┴ ┴ └───────────┘ ┴ ┴ └┘
2447 f [a] ++ sublists_aux₁ l (λ x, f (x ++ [a])) :=
id ┴ ┴┴┴ └┘ └───────────┘ ┴ ┴ ┴ ┴ └┘ ┴┴┴
src ┴ ┴ └┘ └───────────┘ └┘ ┴ ┴
typ ┴ ┴┴┴ └┘ └───────────┘ ┴ ┴ ┴ ┴ └┘ ┴┴┴
2448 by simp only [sublists_aux₁_append, sublists_aux₁, append_assoc, append_nil]
id └──────────────────┘ └───────────┘ └──────────┘ └────────┘
src └─────────┘└──────────────────┘└┘└───────────┘└┘└──────────┘└┘└────────┘└─
typ └─────────┘└──────────────────┘└┘└───────────┘└┘└──────────┘└┘└────────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └──────────────────────────────────────────────────────────────────────────
2449
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2450 theorem sublists_aux₁_bind : ∀ (l : list α)
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
2451 (f : list α → list β) (g : β → list γ),
id └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴
2452 (sublists_aux₁ l f).bind g = sublists_aux₁ l (λ x, (f x).bind g)
id └───────────┘ ┴ ┴ └──┘ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ └──┘ ┴
src └───────────┘ └──┘ ┴ └───────────┘ └──┘
typ └───────────┘ ┴ ┴ └──┘ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴ └──┘ ┴
2453 | [] f g := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2454 | (a::l) f g := by simp only [sublists_aux₁, bind_append, sublists_aux₁_bind l]
id └┘ └───────────┘ └─────────┘ └────────────────┘ ┴
src └┘ └─────────┘└───────────┘└┘└─────────┘└┘ ┴ └─
typ └┘ └─────────┘└───────────┘└┘└─────────┘└┘└────────────────┘┴┴└─
doc └─────────┘ └┘ └┘ ┴ └─
txt └─────────┘ └┘ └┘ ┴ └─
par └─────────┘ └┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴└
st └─────────────────────────────────────────────────────────────
2455
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2456 theorem sublists_aux_cons_append (l₁ l₂ : list α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
2457 sublists_aux (l₁ ++ l₂) cons = sublists_aux l₁ cons ++
id └──────────┘ └┘ └┘ └┘ └──┘ ┴ └──────────┘ └┘ └──┘ └┘
src └──────────┘ └┘ └──┘ ┴ └──────────┘ └──┘ └┘
typ └──────────┘ └┘ └┘ └┘ └──┘ ┴ └──────────┘ └┘ └──┘ └┘
2458 (do x ← sublists_aux l₂ cons, (++ x) <$> sublists l₁) :=
id ┴ └──────────┘ └┘ └──┘ ┴ ┴ └─┘ └──────┘ └┘
src └──────────┘ └──┘ ┴ └─┘ └──────┘
typ ┴ └──────────┘ └┘ └──┘ ┴ ┴ └─┘ └──────┘ └┘
doc └──────┘
2459 begin
st └─────
2460 simp only [sublists, sublists_aux_cons_eq_sublists_aux₁, sublists_aux₁_append, bind_eq_bind, sublists_aux₁_bind],
id └──────┘ └────────────────────────────────┘ └──────────────────┘ └──────────┘ └────────────────┘
src └─────────┘└──────┘└┘└────────────────────────────────┘└┘└──────────────────┘└┘└──────────┘└┘└────────────────┘┴
typ └─────────┘└──────┘└┘└────────────────────────────────┘└┘└──────────────────┘└┘└──────────┘└┘└────────────────┘┴
doc └─────────┘└──────┘└┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴
st ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘└─
2461 congr, funext x, apply congr_arg _,
id └───────┘
src └───┘ └──────┘ └────┘└───────┘└┘
typ └───┘ └──────┘ └────┘└───────┘└┘
doc └──────┘ └────┘ └┘
txt └───┘ └──────┘ └────┘ └┘
par └───┘ └──────┘ └────┘ └┘
pid └┘ ┴ └┘
st ──────┘└────────┘└─────────────────┘└─
2462 rw [← bind_ret_eq_map, sublists_aux₁_bind], exact (append_nil _).symm
id └─────────────┘ └────────────────┘ └────────┘
src └────┘└─────────────┘└┘└────────────────┘┴ └────┘ └────────┘└───────┘
typ └────┘└─────────────┘└┘└────────────────┘┴ └────┘ └────────┘└───────┘
doc └────┘ └┘ ┴ └────┘ └───────┘
txt └────┘ └┘ ┴ └────┘ └───────┘
par └────┘ └┘ ┴ └────┘ └───────┘
pid └──┘ └┘ ┴ ┴ └─────┘└┘
st ──────────────────────┘└──────────────────┘└───────────────────────────┘
2463 end
st └─┘
2464
2465 theorem sublists_append (l₁ l₂ : list α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
2466 sublists (l₁ ++ l₂) = (do x ← sublists l₂, (++ x) <$> sublists l₁) :=
id └──────┘ └┘ └┘ └┘ ┴ ┴ └──────┘ └┘ ┴ ┴ └─┘ └──────┘ └┘
src └──────┘ └┘ ┴ └──────┘ ┴ └─┘ └──────┘
typ └──────┘ └┘ └┘ └┘ ┴ ┴ └──────┘ └┘ ┴ ┴ └─┘ └──────┘ └┘
doc └──────┘ └──────┘ └──────┘
2467 by simp only [map, sublists, sublists_aux_cons_append, map_eq_map, bind_eq_bind,
id └─┘ └──────┘ └──────────────────────┘ └────────┘ └──────────┘
src └─────────┘└─┘└┘└──────┘└┘└──────────────────────┘└┘└────────┘└┘└──────────┘└─
typ └─────────┘└─┘└┘└──────┘└┘└──────────────────────┘└┘└────────┘└┘└──────────┘└─
doc └─────────┘ └┘└──────┘└┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └─
st └──────────────────────────────────────────────────────────────────────────────
2468 cons_bind, map_id', append_nil, cons_append, map_id' (λ _, rfl)]; split; refl
id └───────┘ └─────┘ └────────┘ └─────────┘ └─────┘ └─┘
src ─┘└───────┘└┘└─────┘└┘└────────┘└┘└─────────┘└┘└─────┘┴ └──┘└─┘└┘ └───┘ └────
typ ─┘└───────┘└┘└─────┘└┘└────────┘└┘└─────────┘└┘└─────┘┴ └──┘└─┘└┘ └───┘ └────
doc ─┘ └┘ └┘ └┘ └┘ ┴ └──┘ └┘ └───┘ └────
txt ─┘ └┘ └┘ └┘ └┘ ┴ └──┘ └┘ └───┘ └────
par ─┘ └┘ └┘ └┘ └┘ ┴ └──┘ └┘ └───┘ └────
pid ─┘ └┘ └┘ └┘ └┘ ┴ └──┘ └┘ └
st ────────────────────────────────────────────────────────────────────────────────
2469
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2470 @[simp] theorem sublists_concat (l : list α) (a : α) :
id └──┘ ┴ ┴
src └──┘
typ └──┘ ┴ ┴
doc └──┘
2471 sublists (l ++ [a]) = sublists l ++ map (λ x, x ++ [a]) (sublists l) :=
id └──────┘ ┴ └┘ ┴┴┴ ┴ └──────┘ ┴ └┘ └─┘ ┴ ┴ └┘ ┴┴┴ └──────┘ ┴
src └──────┘ └┘ ┴ ┴ ┴ └──────┘ └┘ └─┘ └┘ ┴ ┴ └──────┘
typ └──────┘ ┴ └┘ ┴┴┴ ┴ └──────┘ ┴ └┘ └─┘ ┴ ┴ └┘ ┴┴┴ └──────┘ ┴
doc └──────┘ └──────┘ └──────┘
2472 by rw [sublists_append, sublists_singleton, bind_eq_bind, cons_bind, cons_bind, nil_bind,
id └─────────────┘ └────────────────┘ └──────────┘ └───────┘ └───────┘ └──────┘
src └──┘└─────────────┘└┘└────────────────┘└┘└──────────┘└┘└───────┘└┘└───────┘└┘└──────┘└─
typ └──┘└─────────────┘└┘└────────────────┘└┘└──────────┘└┘└───────┘└┘└───────┘└┘└──────┘└─
doc └──┘ └┘ └┘ └┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └┘ └┘ └┘ └─
par └──┘ └┘ └┘ └┘ └┘ └┘ └─
pid └┘ └┘ └┘ └┘ └┘ └┘ └─
st └──────────────────┘└──────────────────┘└────────────┘└─────────┘└─────────┘└────────┘└─
2473 map_eq_map, map_eq_map, map_id' (append_nil), append_nil]
id └────────┘ └────────┘ └─────┘ └────────┘ └────────┘
src ─┘└────────┘└┘└────────┘└┘└─────┘┴ └────────┘└─┘└────────┘└─
typ ─┘└────────┘└┘└────────┘└┘└─────┘┴ └────────┘└─┘└────────┘└─
doc ─┘ └┘ └┘ ┴ └─┘ └─
txt ─┘ └┘ └┘ ┴ └─┘ └─
par ─┘ └┘ └┘ ┴ └─┘ └─
pid ─┘ └┘ └┘ ┴ └─┘ ┴└
st ───────────┘└──────────┘└────────────────────┘└──────────┘┴└
2474
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2475 theorem sublists_reverse (l : list α) : sublists (reverse l) = map reverse (sublists' l) :=
id └──┘ ┴ └──────┘ └─────┘ ┴ ┴ └─┘ └─────┘ └───────┘ ┴
src └──┘ └──────┘ └─────┘ ┴ └─┘ └─────┘ └───────┘
typ └──┘ ┴ └──────┘ └─────┘ ┴ ┴ └─┘ └─────┘ └───────┘ ┴
doc └──────┘ └───────┘
2476 by induction l with hd tl ih; [refl,
id ┴ ┴
src └────────┘ └────────────┘ ┴└──┘
typ └────────┘┴└────────────┘ ┴└──┘
doc └────────┘ └────────────┘ └──┘
txt └────────┘ └────────────┘ └──┘
par └────────┘ └────────────┘ └──┘
pid ┴ ┴└───────────┘
st └──────────────────────────────────
2477 simp only [reverse_cons, sublists_append, sublists'_cons, map_append, ih, sublists_singleton,
id └──────────┘ └─────────────┘ └────────────┘ └────────┘ └┘ └────────────────┘
src └─────────┘└──────────┘└┘└─────────────┘└┘└────────────┘└┘└────────┘└┘ └┘└────────────────┘└─
typ └─────────┘└──────────┘└┘└─────────────┘└┘└────────────┘└┘└────────┘└┘└┘└┘└────────────────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └─
st ──────────────────────────────────────────────────────────────────────────────────────────────
2478 map_eq_map, bind_eq_bind, map_map, cons_bind, append_nil, nil_bind, (∘)]]
id └────────┘ └──────────┘ └─────┘ └───────┘ └────────┘ └──────┘ ┴
src ─┘└────────┘└┘└──────────┘└┘└─────┘└┘└───────┘└┘└────────┘└┘└──────┘└┘┴└─┘
typ ─┘└────────┘└┘└──────────┘└┘└─────┘└┘└───────┘└┘└────────┘└┘└──────┘└┘┴└─┘
doc ─┘ └┘ └┘ └┘ └┘ └┘ └┘ └─┘
txt ─┘ └┘ └┘ └┘ └┘ └┘ └┘ └─┘
par ─┘ └┘ └┘ └┘ └┘ └┘ └┘ └─┘
pid ─┘ └┘ └┘ └┘ └┘ └┘ └┘ └─┘
st ──────────────────────────────────────────────────────────────────────────┘
2479
2480 theorem sublists_eq_sublists' (l : list α) : sublists l = map reverse (sublists' (reverse l)) :=
id └──┘ ┴ └──────┘ ┴ ┴ └─┘ └─────┘ └───────┘ └─────┘ ┴
src └──┘ └──────┘ ┴ └─┘ └─────┘ └───────┘ └─────┘
typ └──┘ ┴ └──────┘ ┴ ┴ └─┘ └─────┘ └───────┘ └─────┘ ┴
doc └──────┘ └───────┘
2481 by rw [← sublists_reverse, reverse_reverse]
id └──────────────┘ └─────────────┘
src └────┘└──────────────┘└┘└─────────────┘└─
typ └────┘└──────────────┘└┘└─────────────┘└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid └──┘ └┘ ┴└
st └─────────────────────┘└───────────────┘┴└
2482
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2483 theorem sublists'_reverse (l : list α) : sublists' (reverse l) = map reverse (sublists l) :=
id └──┘ ┴ └───────┘ └─────┘ ┴ ┴ └─┘ └─────┘ └──────┘ ┴
src └──┘ └───────┘ └─────┘ ┴ └─┘ └─────┘ └──────┘
typ └──┘ ┴ └───────┘ └─────┘ ┴ ┴ └─┘ └─────┘ └──────┘ ┴
doc └───────┘ └──────┘
2484 by simp only [sublists_eq_sublists', map_map, map_id' (reverse_reverse)]
id └───────────────────┘ └─────┘ └─────┘ └─────────────┘
src └─────────┘└───────────────────┘└┘└─────┘└┘└─────┘┴ └─────────────┘└──
typ └─────────┘└───────────────────┘└┘└─────┘└┘└─────┘┴ └─────────────┘└──
doc └─────────┘ └┘ └┘ ┴ └──
txt └─────────┘ └┘ └┘ ┴ └──
par └─────────┘ └┘ └┘ ┴ └──
pid ┴└──┘└┘ └┘ └┘ ┴ └┘└
st └──────────────────────────────────────────────────────────────────────
2485
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2486 theorem sublists'_eq_sublists (l : list α) : sublists' l = map reverse (sublists (reverse l)) :=
id └──┘ ┴ └───────┘ ┴ ┴ └─┘ └─────┘ └──────┘ └─────┘ ┴
src └──┘ └───────┘ ┴ └─┘ └─────┘ └──────┘ └─────┘
typ └──┘ ┴ └───────┘ ┴ ┴ └─┘ └─────┘ └──────┘ └─────┘ ┴
doc └───────┘ └──────┘
2487 by rw [← sublists'_reverse, reverse_reverse]
id └───────────────┘ └─────────────┘
src └────┘└───────────────┘└┘└─────────────┘└─
typ └────┘└───────────────┘└┘└─────────────┘└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid └──┘ └┘ ┴└
st └──────────────────────┘└───────────────┘┴└
2488
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2489 theorem sublists_aux_ne_nil : ∀ (l : list α), [] ∉ sublists_aux l cons
id ┴ └──┘ ┴ └┘ ┴ └──────────┘ ┴ └──┘
src └──┘ └┘ ┴ └──────────┘ └──┘
typ ┴ └──┘ ┴ └┘ ┴ └──────────┘ ┴ └──┘
2490 | [] := id
id └┘ └┘
src └┘ └┘
typ └┘ └┘
2491 | (a::l) := begin
id └┘
src └┘
typ └┘
st └─────
2492 rw [sublists_aux_cons_cons],
id └────────────────────┘
src └──┘└────────────────────┘┴
typ └──┘└────────────────────┘┴
doc └──┘ ┴
txt └──┘ ┴
par └──┘ ┴
pid └┘ ┴
st ───────────────────────────┘└──
2493 refine not_mem_cons_of_ne_of_not_mem (cons_ne_nil _ _).symm _,
id └───────────────────────────┘ └─────────┘
src └─────┘└───────────────────────────┘┴ └─────────┘└──────────┘
typ └─────┘└───────────────────────────┘┴ └─────────┘└──────────┘
doc └─────┘ ┴ └──────────┘
txt └─────┘ ┴ └──────────┘
par └─────┘ ┴ └──────────┘
pid ┴ ┴ └──────────┘
st ──────────────────────────────────────────────────────────────┘└─
2494 have := sublists_aux_ne_nil l, revert this,
id └─────────────────┘ ┴
src └──────┘ ┴ └─────────┘
typ └──────┘└─────────────────┘┴┴ └─────────┘
doc └──────┘ ┴ └─────────┘
txt └──────┘ ┴ └─────────┘
par └──────┘ ┴ └─────────┘
pid └───┘└─┘ ┴ └───┘
st ──────────────────────────────┘└───────────┘└─
2495 induction sublists_aux l cons; intro, {rwa foldr},
id └──────────┘ ┴ └──┘ └───┘
src └────────┘└──────────┘┴ ┴└──┘ └───┘ └──┘└───┘
typ └────────┘└──────────┘┴┴┴└──┘ └───┘ └──┘└───┘
doc └────────┘ ┴ ┴ └───┘ └──┘
txt └────────┘ ┴ ┴ └───┘ └──┘
par └────────┘ ┴ ┴ └───┘ └──┘
pid ┴ ┴ ┴ ┴
st ─────────────────────────────────────┘└─────┘└───┘└┘└
2496 simp only [foldr, mem_cons_iff, false_or, not_or_distrib],
id └───┘ └──────────┘ └──────┘ └────────────┘
src └─────────┘└───┘└┘└──────────┘└┘└──────┘└┘└────────────┘┴
typ └─────────┘└───┘└┘└──────────┘└┘└──────┘└┘└────────────┘┴
doc └─────────┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ ┴
st ──────────────────────────────────────────────────────────┘└─
2497 exact ⟨ne_of_not_mem_cons this, ih (not_mem_of_not_mem_cons this)⟩
id └────────────────┘ └┘ └─────────────────────┘ └──┘
src └────┘ └────────────────┘┴ └┘ ┴ └─────────────────────┘┴ └─┘
typ └────┘ └────────────────┘┴ └┘└┘┴ └─────────────────────┘┴└──┘└─┘
doc └────┘ ┴ └┘ ┴ ┴ └─┘
txt └────┘ ┴ └┘ ┴ ┴ └─┘
par └────┘ ┴ └┘ ┴ ┴ └─┘
pid ┴ ┴ └┘ ┴ ┴ └┘┴
st ────────────────────────────────────────────────────────────────────┘
2498 end
st └─┘
2499
2500 @[simp] theorem mem_sublists {s t : list α} : s ∈ sublists t ↔ s <+ t :=
id └──┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └┘ ┴
src └──┘ ┴ └──────┘ ┴ └┘
typ └──┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └┘ ┴
doc └──┘ └──────┘
2501 by rw [← reverse_sublist_iff, ← mem_sublists',
id └─────────────────┘ └───────────┘
src └────┘└─────────────────┘└──┘└───────────┘└─
typ └────┘└─────────────────┘└──┘└───────────┘└─
doc └────┘ └──┘ └─
txt └────┘ └──┘ └─
par └────┘ └──┘ └─
pid └──┘ └──┘ └─
st └────────────────────────┘└───────────────┘└─
2502 sublists'_reverse, mem_map_of_inj reverse_injective]
id └───────────────┘ └────────────┘ └───────────────┘
src ──────┘└───────────────┘└┘└────────────┘┴└───────────────┘└─
typ ──────┘└───────────────┘└┘└────────────┘┴└───────────────┘└─
doc ──────┘ └┘ ┴ └─
txt ──────┘ └┘ ┴ └─
par ──────┘ └┘ ┴ └─
pid ──────┘ └┘ ┴ ┴└
st ───────────────────────┘└────────────────────────────────┘┴└
2503
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2504 @[simp] theorem length_sublists (l : list α) : length (sublists l) = 2 ^ length l :=
id └──┘ ┴ └────┘ └──────┘ ┴ ┴ ┴ └────┘ ┴
src └──┘ └────┘ └──────┘ ┴ ┴ └────┘
typ └──┘ ┴ └────┘ └──────┘ ┴ ┴ ┴ └────┘ ┴
doc └──┘ └──────┘
2505 by simp only [sublists_eq_sublists', length_map, length_sublists', length_reverse]
id └───────────────────┘ └────────┘ └──────────────┘ └────────────┘
src └─────────┘└───────────────────┘└┘└────────┘└┘└──────────────┘└┘└────────────┘└─
typ └─────────┘└───────────────────┘└┘└────────┘└┘└──────────────┘└┘└────────────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────────────────────
2506
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2507 theorem map_ret_sublist_sublists (l : list α) : map list.ret l <+ sublists l :=
id └──┘ ┴ └─┘ └──────┘ ┴ └┘ └──────┘ ┴
src └──┘ └─┘ └──────┘ └┘ └──────┘
typ └──┘ ┴ └─┘ └──────┘ ┴ └┘ └──────┘ ┴
doc └──────┘
2508 reverse_rec_on l (nil_sublist _) $
id └────────────┘ ┴ └─────────┘
src └────────────┘ └─────────┘
typ └────────────┘ ┴ └─────────┘
2509 λ l a IH, by simp only [map, map_append, sublists_concat]; exact
id ┴ ┴ └┘ └─┘ └────────┘ └─────────────┘
src └─────────┘└─┘└┘└────────┘└┘└─────────────┘┴ └────┘
typ ┴ ┴ └┘ └─────────┘└─┘└┘└────────┘└┘└─────────────┘┴ └────┘
doc └─────────┘ └┘ └┘ ┴ └────┘
txt └─────────┘ └┘ └┘ ┴ └────┘
par └─────────┘ └┘ └┘ ┴ └────┘
pid ┴└──┘└┘ └┘ └┘ ┴ ┴
st └────────────────────────────────────────────────────
2510 ((append_sublist_append_left _).2 $ singleton_sublist.2 $
id └────────────────────────┘ └───────────────┘
src └────────────────────────┘└────┘ ┴└───────────────┘└─┘ └
typ └────────────────────────┘└────┘ ┴└───────────────┘└─┘ └
doc └────┘ ┴ └─┘ └
txt └────┘ ┴ └─┘ └
par └────┘ ┴ └─┘ └
pid └────┘ ┴ └─┘ └
st ──────────────────────────────────────────────────────────
2511 mem_map.2 ⟨[], mem_sublists.2 (nil_sublist _), by refl⟩).trans
id └─────┘ └──────────┘ └─────────┘
src ─┘└─────┘└─┘ └┘└──────────┘└─┘ └─────────┘└───┘ ┴└──┘└───────┘
typ ─┘└─────┘└─┘ └┘└──────────┘└─┘ └─────────┘└───┘ ┴└──┘└───────┘
doc ─┘ └─┘ └┘ └─┘ └───┘ ┴└──┘└───────┘
txt ─┘ └─┘ └┘ └─┘ └───┘ ┴└──┘└───────┘
par ─┘ └─┘ └┘ └─┘ └───┘ ┴└──┘└───────┘
pid ─┘ └─┘ └┘ └─┘ └───┘ └────────────┘
st ──────────────────────────────────────────────────┘└───┘└────────
2512 ((append_sublist_append_right _).2 IH)
id └─────────────────────────┘ └┘
src └─────────────────────────┘└────┘ └─
typ └─────────────────────────┘└────┘└┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid └────┘ ┴└
st ───────────────────────────────────────
2513
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
2514 /- sublists_len -/
src ───────────────────
typ ───────────────────
doc ───────────────────
txt ───────────────────
par ───────────────────
pid ───────────────────
st ───────────────────
2515
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2516 def sublists_len_aux {α β : Type*} : ℕ → list α → (list α → β) → list β → list β
id ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
src ┴ └──┘ └──┘ └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
2517 | 0 l f r := f [] :: r
id ┴ ┴ └┘ └┘
src └┘ └┘
typ ┴ ┴ └┘ └┘
2518 | (n+1) [] f r := r
id ┴ └┘ ┴
src ┴ └┘
typ ┴ └┘ ┴
2519 | (n+1) (a::l) f r := sublists_len_aux (n + 1) l f
id ┴┴ ┴└┘┴ ┴ ┴ └──────────────┘ ┴
src ┴ └┘ ┴
typ ┴┴ ┴└┘┴ ┴ ┴ └──────────────┘ ┴
2520 (sublists_len_aux n l (f ∘ list.cons a) r)
id └──────────────┘ ┴ └───────┘
src ┴ └───────┘
typ └──────────────┘ ┴ └───────┘
2521
2522 def sublists_len {α : Type*} (n : ℕ) (l : list α) : list (list α) :=
id ┴ └──┘ ┴ └──┘ └──┘ ┴
src ┴ └──┘ └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ └──┘ ┴
2523 sublists_len_aux n l id []
id └──────────────┘ ┴ ┴ └┘ └┘
src └──────────────┘ └┘ └┘
typ └──────────────┘ ┴ ┴ └┘ └┘
2524
2525 lemma sublists_len_aux_append {α β γ : Type*} :
2526 ∀ (n : ℕ) (l : list α) (f : list α → β) (g : β → γ) (r : list β) (s : list γ),
id ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
src ┴ └──┘ └──┘ └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
2527 sublists_len_aux n l (g ∘ f) (r.map g ++ s) =
id └──────────────┘ ┴ ┴ ┴ ┴ ┴ ┴└──┘ ┴ └┘ ┴ ┴
src └──────────────┘ ┴ └──┘ └┘ ┴
typ └──────────────┘ ┴ ┴ ┴ ┴ ┴ ┴└──┘ ┴ └┘ ┴ ┴
2528 (sublists_len_aux n l f r).map g ++ s
id └──────────────┘ ┴ ┴ ┴ ┴ └─┘ ┴ └┘ ┴
src └──────────────┘ └─┘ └┘
typ └──────────────┘ ┴ ┴ ┴ ┴ └─┘ ┴ └┘ ┴
2529 | 0 l f g r s := rfl
id └─┘
src └─┘
typ └─┘
2530 | (n+1) [] f g r s := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
2531 | (n+1) (a::l) f g r s := begin
id ┴ └┘
src ┴ └┘
typ ┴ └┘
st └─────
2532 unfold sublists_len_aux,
src └─────────────────────┘
typ └─────────────────────┘
doc └─────────────────────┘
txt └─────────────────────┘
par └─────────────────────┘
pid └───────────────┘
st ────────────────────────┘└─
2533 rw [show ((g ∘ f) ∘ list.cons a) = (g ∘ f ∘ list.cons a), by refl,
id ┴ ┴ ┴ ┴ └───────┘ ┴
src └──┘ ┴ ┴┴┴ └┘ ┴ ┴ └┘┴┴ ┴ ┴ ┴ ┴└───────┘┴ └────┘└──┘└─
typ └──┘ ┴ ┴┴┴ └┘ ┴ ┴ └┘┴┴ ┴┴ ┴┴┴ ┴└───────┘┴┴└────┘└──┘└─
doc └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘└──┘└─
txt └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘└──┘└─
par └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘└──┘└─
pid └┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ └───────────
st ─────────────────────────────────────────────────────────────┘└───┘└─
2534 sublists_len_aux_append, sublists_len_aux_append]
id └─────────────────────┘ └─────────────────────┘
src ───┘ └┘ └┘
typ ───┘└─────────────────────┘└┘└─────────────────────┘└┘
doc ───┘ └┘ └┘
txt ───┘ └┘ └┘
par ───┘ └┘ └┘
pid ───┘ └┘ ┴┴
st ──────────────────────────┘└───────────────────────┘┴┴
2535 end
st └─┘
2536
2537 lemma sublists_len_aux_eq {α β : Type*} (l : list α) (n) (f : list α → β) (r) :
id └──┘ ┴ └──┘ ┴ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ ┴
2538 sublists_len_aux n l f r = (sublists_len n l).map f ++ r :=
id └──────────────┘ ┴ ┴ ┴ ┴ ┴ └──────────┘ ┴ ┴ └─┘ ┴ └┘ ┴
src └──────────────┘ ┴ └──────────┘ └─┘ └┘
typ └──────────────┘ ┴ ┴ ┴ ┴ ┴ └──────────┘ ┴ ┴ └─┘ ┴ └┘ ┴
2539 by rw [sublists_len, ← sublists_len_aux_append]; refl
id └──────────┘ └─────────────────────┘
src └──┘└──────────┘└──┘└─────────────────────┘┴ └────
typ └──┘└──────────┘└──┘└─────────────────────┘┴ └────
doc └──┘ └──┘ ┴ └────
txt └──┘ └──┘ ┴ └────
par └──┘ └──┘ ┴ └────
pid └┘ └──┘ ┴ └
st └───────────────┘└─────────────────────────┘┴└──────
2540
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2541 lemma sublists_len_aux_zero {α : Type*} (l : list α) (f : list α → β) (r) :
id └──┘ ┴ └──┘ ┴ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ ┴
2542 sublists_len_aux 0 l f r = f [] :: r := by cases l; refl
id └──────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴
src └──────────────┘ ┴ └┘ └┘ └────┘ └────
typ └──────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
2543
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2544 @[simp] lemma sublists_len_zero {α : Type*} (l : list α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
2545 sublists_len 0 l = [[]] := sublists_len_aux_zero _ _ _
id └──────────┘ ┴ ┴ ┴└┘┴ └───────────────────┘
src └──────────┘ ┴ └──┘ └───────────────────┘
typ └──────────┘ ┴ ┴ ┴└┘┴ └───────────────────┘
2546
2547 @[simp] lemma sublists_len_succ_nil {α : Type*} (n) :
doc └──┘
2548 sublists_len (n+1) (@nil α) = [] := rfl
id └──────────┘ ┴┴ └─┘ ┴ ┴ └┘ └─┘
src └──────────┘ ┴ └─┘ ┴ └┘ └─┘
typ └──────────┘ ┴┴ └─┘ ┴ ┴ └┘ └─┘
2549
2550 @[simp] lemma sublists_len_succ_cons {α : Type*} (n) (a : α) (l) :
id ┴
typ ┴
doc └──┘
2551 sublists_len (n + 1) (a::l) =
id └──────────┘ ┴ ┴ ┴└┘┴ ┴
src └──────────┘ ┴ └┘ ┴
typ └──────────┘ ┴ ┴ ┴└┘┴ ┴
2552 sublists_len (n + 1) l ++ (sublists_len n l).map (cons a) :=
id └──────────┘ ┴ ┴ ┴ └┘ └──────────┘ ┴ ┴ └─┘ └──┘ ┴
src └──────────┘ ┴ └┘ └──────────┘ └─┘ └──┘
typ └──────────┘ ┴ ┴ ┴ └┘ └──────────┘ ┴ ┴ └─┘ └──┘ ┴
2553 by rw [sublists_len, sublists_len_aux, sublists_len_aux_eq,
id └──────────┘ └──────────────┘ └─────────────────┘
src └──┘└──────────┘└┘└──────────────┘└┘└─────────────────┘└─
typ └──┘└──────────┘└┘└──────────────┘└┘└─────────────────┘└─
doc └──┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ └─
st └───────────────┘└────────────────┘└───────────────────┘└─
2554 sublists_len_aux_eq, map_id, append_nil]; refl
id └─────────────────┘ └────┘ └────────┘
src ─┘└─────────────────┘└┘└────┘└┘└────────┘┴ └────
typ ─┘└─────────────────┘└┘└────┘└┘└────────┘┴ └────
doc ─┘ └┘ └┘ ┴ └────
txt ─┘ └┘ └┘ ┴ └────
par ─┘ └┘ └┘ ┴ └────
pid ─┘ └┘ └┘ ┴ └
st ────────────────────┘└──────┘└──────────┘┴└──────
2555
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2556 @[simp] lemma length_sublists_len {α : Type*} : ∀ n (l : list α),
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
2557 length (sublists_len n l) = nat.choose (length l) n
id └────┘ └──────────┘ ┴ ┴ ┴ └────────┘ └────┘ ┴ ┴
src └────┘ └──────────┘ ┴ └────────┘ └────┘
typ └────┘ └──────────┘ ┴ ┴ ┴ └────────┘ └────┘ ┴ ┴
doc └────────┘
2558 | 0 l := by simp
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
2559 | (n+1) [] := by simp
id ┴ └┘
src ┴ └┘ └───┘
typ ┴ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
2560 | (n+1) (a::l) := by simp [-add_comm, nat.choose, *]; apply add_comm
id ┴ └┘ └────────┘ └──────┘
src ┴ └┘ └───────────────┘└────────┘└──┘ └────┘└──────┘└
typ ┴ └┘ └───────────────┘└────────┘└──┘ └────┘└──────┘└
doc └───────────────┘└────────┘└──┘ └────┘ └
txt └───────────────┘ └──┘ └────┘ └
par └───────────────┘ └──┘ └────┘ └
pid ┴└──────────┘ └──┘ ┴ └
st └────────────────────────────────────────────────
2561
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2562 lemma sublists_len_sublist_sublists' {α : Type*} : ∀ n (l : list α),
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
2563 sublists_len n l <+ sublists' l
id └──────────┘ ┴ ┴ └┘ └───────┘ ┴
src └──────────┘ └┘ └───────┘
typ └──────────┘ ┴ ┴ └┘ └───────┘ ┴
doc └───────┘
2564 | 0 l := singleton_sublist.2 (mem_sublists'.2 (nil_sublist _))
id └───────────────┘┴ └───────────┘┴ └─────────┘
src └───────────────┘┴ └───────────┘┴ └─────────┘
typ └───────────────┘┴ └───────────┘┴ └─────────┘
2565 | (n+1) [] := nil_sublist _
id ┴ └┘ └─────────┘
src ┴ └┘ └─────────┘
typ ┴ └┘ └─────────┘
2566 | (n+1) (a::l) := begin
id ┴ └┘
src ┴ └┘
typ ┴ └┘
st └─────
2567 rw [sublists_len_succ_cons, sublists'_cons],
id └────────────────────┘ └────────────┘
src └──┘└────────────────────┘└┘└────────────┘┴
typ └──┘└────────────────────┘└┘└────────────┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ───────────────────────────┘└──────────────┘└──
2568 exact append_sublist_append
id └───────────────────┘
src └────┘└───────────────────┘└
typ └────┘└───────────────────┘└
doc └────┘ └
txt └────┘ └
par └────┘ └
pid ┴ └
st ──────────────────────────────
2569 (sublists_len_sublist_sublists' _ _)
src ───┘ └─────
typ ───┘ └─────
doc ───┘ └─────
txt ───┘ └─────
par ───┘ └─────
pid ───┘ └─────
st ─────────────────────────────────────────
2570 (map_sublist_map _ (sublists_len_sublist_sublists' _ _))
id └─────────────┘ └────────────────────────────┘
src ───┘ └─────────────┘└─┘ └─────┘
typ ───┘ └─────────────┘└─┘ └────────────────────────────┘└─────┘
doc ───┘ └─┘ └─────┘
txt ───┘ └─┘ └─────┘
par ───┘ └─┘ └─────┘
pid ───┘ └─┘ └────┘┴
st ────────────────────────────────────────────────────────────┘
2571 end
st └─┘
2572
2573 lemma sublists_len_sublist_of_sublist
2574 {α : Type*} (n) {l₁ l₂ : list α} (h : l₁ <+ l₂) : sublists_len n l₁ <+ sublists_len n l₂ :=
id └──┘ ┴ └┘ └┘ └┘ └──────────┘ ┴ └┘ └┘ └──────────┘ ┴ └┘
src └──┘ └┘ └──────────┘ └┘ └──────────┘
typ └──┘ ┴ └┘ └┘ └┘ └──────────┘ ┴ └┘ └┘ └──────────┘ ┴ └┘
2575 begin
st └─────
2576 induction n with n IHn generalizing l₁ l₂, {simp},
id ┴
src └────────┘ └────────────────────────────┘ └──┘
typ └────────┘┴└────────────────────────────┘ └──┘
doc └────────┘ └────────────────────────────┘ └──┘
txt └────────┘ └────────────────────────────┘ └──┘
par └────────┘ └────────────────────────────┘ └──┘
pid ┴ ┴└────────┘└─────────────────┘
st ──────────────────────────────────────────┘└─────┘└┘└
2577 induction h with l₁ l₂ a s IH l₁ l₂ a s IH, {refl},
id ┴
src └────────┘ └─────────────────────────────┘ └──┘
typ └────────┘┴└─────────────────────────────┘ └──┘
doc └────────┘ └─────────────────────────────┘ └──┘
txt └────────┘ └─────────────────────────────┘ └──┘
par └────────┘ └─────────────────────────────┘ └──┘
pid ┴ ┴└────────────────────────────┘
st ───────────────────────────────────────────┘└─────┘└┘└
2578 { refine IH.trans _,
id └──────┘
src └─────┘└──────┘└┘
typ └─────┘└──────┘└┘
doc └─────┘ └┘
txt └─────┘ └┘
par └─────┘ └┘
pid ┴ └┘
st ───┘└───────────────┘└─
2579 rw sublists_len_succ_cons,
id └────────────────────┘
src └─┘└────────────────────┘
typ └─┘└────────────────────┘
doc └─┘
txt └─┘
par └─┘
pid ┴
st ────────────────────────────┘└─
2580 apply sublist_append_left },
id └─────────────────┘
src └────┘└─────────────────┘┴
typ └────┘└─────────────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ─────────────────────────────┘└┘└
2581 { simp [sublists_len_succ_cons],
id └────────────────────┘
src └────┘└────────────────────┘┴
typ └────┘└────────────────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴┴ ┴
st ────────────────────────────────┘└─
2582 exact append_sublist_append IH (map_sublist_map _ (IHn s)) }
id └───────────────────┘ └┘ └─────────────┘ └─┘ ┴
src └────┘└───────────────────┘┴ ┴ └─────────────┘└─┘ ┴ └─┘
typ └────┘└───────────────────┘┴└┘┴ └─────────────┘└─┘ └─┘┴┴└─┘
doc └────┘ ┴ ┴ └─┘ ┴ └─┘
txt └────┘ ┴ ┴ └─┘ ┴ └─┘
par └────┘ ┴ ┴ └─┘ ┴ └─┘
pid ┴ ┴ ┴ └─┘ ┴ └┘┴
st ──────────────────────────────────────────────────────────────┘└─
2583 end
st ──┘
2584
2585 lemma length_of_sublists_len {α : Type*} : ∀ {n} {l l' : list α},
id ┴┴ └──┘ ┴
src └──┘
typ ┴┴ └──┘ ┴
2586 l' ∈ sublists_len n l → length l' = n
id └┘ ┴ └──────────┘ ┴ ┴ └────┘ └┘ ┴ ┴
src ┴ └──────────┘ └────┘ ┴
typ └┘ ┴ └──────────┘ ┴ ┴ └────┘ └┘ ┴ ┴
2587 | 0 l l' (or.inl rfl) := rfl
id └────┘ └─┘ └─┘
src └────┘ └─┘ └─┘
typ └────┘ └─┘ └─┘
2588 | (n+1) (a::l) l' h := begin
id ┴ └┘
src ┴ └┘
typ ┴ └┘
st └─────
2589 rw [sublists_len_succ_cons, mem_append, mem_map] at h,
id └────────────────────┘ └────────┘ └─────┘
src └──┘└────────────────────┘└┘└────────┘└┘└─────┘└────┘
typ └──┘└────────────────────┘└┘└────────┘└┘└─────┘└────┘
doc └──┘ └┘ └┘ └────┘
txt └──┘ └┘ └┘ └────┘
par └──┘ └┘ └┘ └────┘
pid └┘ └┘ └┘ ┴└───┘
st ───────────────────────────┘└──────────┘└───────┘┴└───┘└─
2590 rcases h with h | ⟨l', h, rfl⟩,
id ┴
src └─────┘ └────────────────────┘
typ └─────┘┴└────────────────────┘
doc └─────┘ └────────────────────┘
txt └─────┘ └────────────────────┘
par └─────┘ └────────────────────┘
pid ┴ └────────────────────┘
st ───────────────────────────────┘└─
2591 { exact length_of_sublists_len h },
id └────────────────────┘ ┴
src └────┘ ┴ ┴
typ └────┘└────────────────────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ───┘└─────────────────────────────┘└┘└
2592 { exact congr_arg (+1) (length_of_sublists_len h) },
id └───────┘ ┴ └────────────────────┘ ┴
src └────┘└───────┘┴┴└──┘ ┴ └┘
typ └────┘└───────┘┴┴└──┘ └────────────────────┘┴┴└┘
doc └────┘ ┴ └──┘ ┴ └┘
txt └────┘ ┴ └──┘ ┴ └┘
par └────┘ ┴ └──┘ ┴ └┘
pid ┴ ┴ └──┘ ┴ ┴┴
st ───────────────────────────────────────────────────┘└──
2593 end
st ──┘
2594
2595 lemma mem_sublists_len_self {α : Type*} {l l' : list α}
id └──┘ ┴
src └──┘
typ └──┘ ┴
2596 (h : l' <+ l) : l' ∈ sublists_len (length l') l :=
id └┘ └┘ ┴ └┘ ┴ └──────────┘ └────┘ └┘ ┴
src └┘ ┴ └──────────┘ └────┘
typ └┘ └┘ ┴ └┘ ┴ └──────────┘ └────┘ └┘ ┴
2597 begin
st └─────
2598 induction h with l₁ l₂ a s IH l₁ l₂ a s IH,
id ┴
src └────────┘ └─────────────────────────────┘
typ └────────┘┴└─────────────────────────────┘
doc └────────┘ └─────────────────────────────┘
txt └────────┘ └─────────────────────────────┘
par └────────┘ └─────────────────────────────┘
pid ┴ ┴└────────────────────────────┘
st ───────────────────────────────────────────┘└─
2599 { exact or.inl rfl },
id └────┘ └─┘
src └────┘└────┘┴└─┘┴
typ └────┘└────┘┴└─┘┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ───┘└───────────────┘└┘└
2600 { cases l₁ with b l₁,
id └┘
src └────┘ └────────┘
typ └────┘└┘└────────┘
doc └────┘ └────────┘
txt └────┘ └────────┘
par └────┘ └────────┘
pid ┴ └────────┘
st ───┘└────────────────┘└─
2601 { exact or.inl rfl },
id └────┘ └─┘
src └────┘└────┘┴└─┘┴
typ └────┘└────┘┴└─┘┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ─────┘└───────────────┘└┘└
2602 { rw [length, sublists_len_succ_cons],
id └────┘ └────────────────────┘
src └──┘└────┘└┘└────────────────────┘┴
typ └──┘└────┘└┘└────────────────────┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ───────────────┘└──────────────────────┘┴└─
2603 exact mem_append_left _ IH } },
id └─────────────┘ └┘
src └────┘└─────────────┘└─┘ ┴
typ └────┘└─────────────┘└─┘└┘┴
doc └────┘ └─┘ ┴
txt └────┘ └─┘ ┴
par └────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ────────────────────────────────┘└──┘└
2604 { rw [length, sublists_len_succ_cons],
id └────┘ └────────────────────┘
src └──┘└────┘└┘└────────────────────┘┴
typ └──┘└────┘└┘└────────────────────┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ─────────────┘└──────────────────────┘┴└─
2605 exact mem_append_right _ (mem_map.2 ⟨_, IH, rfl⟩) }
id └──────────────┘ └─────┘ └┘ └─┘
src └────┘└──────────────┘└─┘ └─────┘└─┘ └─┘ └┘└─┘└─┘
typ └────┘└──────────────┘└─┘ └─────┘└─┘ └─┘└┘└┘└─┘└─┘
doc └────┘ └─┘ └─┘ └─┘ └┘ └─┘
txt └────┘ └─┘ └─┘ └─┘ └┘ └─┘
par └────┘ └─┘ └─┘ └─┘ └┘ └─┘
pid ┴ └─┘ └─┘ └─┘ └┘ └┘┴
st ─────────────────────────────────────────────────────┘└─
2606 end
st ──┘
2607
2608 @[simp] lemma mem_sublists_len {α : Type*} {n} {l l' : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
2609 l' ∈ sublists_len n l ↔ l' <+ l ∧ length l' = n :=
id └┘ ┴ └──────────┘ ┴ ┴ ┴ └┘ └┘ ┴ ┴ └────┘ └┘ ┴ ┴
src ┴ └──────────┘ ┴ └┘ ┴ └────┘ ┴
typ └┘ ┴ └──────────┘ ┴ ┴ ┴ └┘ └┘ ┴ ┴ └────┘ └┘ ┴ ┴
2610 ⟨λ h, ⟨mem_sublists'.1
id ┴ └───────────┘┴
src └───────────┘┴
typ ┴ └───────────┘┴
2611 (subset_of_sublist (sublists_len_sublist_sublists' _ _) h),
id └───────────────┘ └────────────────────────────┘ ┴
src └───────────────┘ └────────────────────────────┘
typ └───────────────┘ └────────────────────────────┘ ┴
2612 length_of_sublists_len h⟩,
id └────────────────────┘ ┴
src └────────────────────┘
typ └────────────────────┘ ┴
2613 λ ⟨h₁, h₂⟩, h₂ ▸ mem_sublists_len_self h₁⟩
id ┴└┘ └┘ ┴ └───────────────────┘
src ┴ └───────────────────┘
typ ┴└┘ └┘ ┴ └───────────────────┘
2614
2615 /- forall₂ -/
2616
2617 section forall₂
2618 variables {r : α → β → Prop} {p : γ → δ → Prop}
2619 open relator
2620
2621 run_cmd tactic.mk_iff_of_inductive_prop `list.forall₂ `list.forall₂_iff
id └─────────────────────────────┘ ┴ ┴
src └─────────────────────────────┘ ┴ ┴
typ └─────────────────────────────┘ ┴ ┴
doc └─────────────────────────────┘
2622
2623 @[simp] theorem forall₂_cons {R : α → β → Prop} {a b l₁ l₂} :
id ┴ ┴
typ ┴ ┴
doc └──┘
2624 forall₂ R (a::l₁) (b::l₂) ↔ R a b ∧ forall₂ R l₁ l₂ :=
id └─────┘ ┴ ┴└┘└┘ ┴└┘└┘ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ └┘ └┘
src └─────┘ └┘ └┘ ┴ ┴ └─────┘
typ └─────┘ ┴ ┴└┘└┘ ┴└┘└┘ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ └┘ └┘
2625 ⟨λ h, by cases h with h₁ h₂; split; assumption, λ ⟨h₁, h₂⟩, forall₂.cons h₁ h₂⟩
id ┴ ┴ ┴└┘ └┘ └──────────┘
src └────┘ └─────────┘ └───┘ └────────┘ └──────────┘
typ ┴ └────┘┴└─────────┘ └───┘ └────────┘ ┴└┘ └┘ └──────────┘
doc └────┘ └─────────┘ └───┘ └────────┘
txt └────┘ └─────────┘ └───┘ └────────┘
par └────┘ └─────────┘ └───┘ └────────┘
pid ┴ └─────────┘
st └────────────────────────────────────┘
2626
2627 theorem forall₂.imp {R S : α → β → Prop}
id ┴ ┴
typ ┴ ┴
2628 (H : ∀ a b, R a b → S a b) {l₁ l₂}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
2629 (h : forall₂ R l₁ l₂) : forall₂ S l₁ l₂ :=
id └─────┘ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘
src └─────┘ └─────┘
typ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘
2630 by induction h; constructor; solve_by_elim
id ┴
src └────────┘ └─────────┘ └─────────────
typ └────────┘┴ └─────────┘ └─────────────
doc └────────┘ └─────────┘ └─────────────
txt └────────┘ └─────────┘ └─────────────
par └────────┘ └─────────┘ └─────────────
pid ┴ └
st └────────────────────────────────────────
2631
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2632 lemma forall₂.mp {r q s : α → β → Prop} (h : ∀a b, r a b → q a b → s a b) :
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
2633 ∀{l₁ l₂}, forall₂ r l₁ l₂ → forall₂ q l₁ l₂ → forall₂ s l₁ l₂
id ┴└┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘
src └─────┘ └─────┘ └─────┘
typ ┴└┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘
2634 | [] [] forall₂.nil forall₂.nil := forall₂.nil
id └┘ └┘ └─────────┘ └─────────┘
src └┘ └┘ └─────────┘ └─────────┘
typ └┘ └┘ └─────────┘ └─────────┘
2635 | (a::l₁) (b::l₂) (forall₂.cons hr hrs) (forall₂.cons hq hqs) :=
id ┴└┘ ┴└┘ └┘ └─┘ └──────────┘ └┘ └─┘
src └┘ └┘ └──────────┘
typ ┴└┘ ┴└┘ └┘ └─┘ └──────────┘ └┘ └─┘
2636 forall₂.cons (h a b hr hq) (forall₂.mp hrs hqs)
id └──────────┘ ┴ └────────┘
src └──────────┘
typ └──────────┘ ┴ └────────┘
2637
2638 lemma forall₂.flip : ∀{a b}, forall₂ (flip r) b a → forall₂ r a b
id ┴┴ ┴ └─────┘ └──┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
src └─────┘ └──┘ └─────┘
typ ┴┴ ┴ └─────┘ └──┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
2639 | _ _ forall₂.nil := forall₂.nil
id └─────────┘ └─────────┘
src └─────────┘ └─────────┘
typ └─────────┘ └─────────┘
2640 | (a :: as) (b :: bs) (forall₂.cons h₁ h₂) := forall₂.cons h₁ h₂.flip
id └┘ └┘ └──────────┘ └┘ └┘ └──────────┘
src └┘ └┘ └──────────┘ └──────────┘
typ └┘ └┘ └──────────┘ └┘ └┘ └──────────┘
2641
2642 lemma forall₂_same {r : α → α → Prop} : ∀{l}, (∀x∈l, r x x) → forall₂ r l l
id ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
src └─────┘
typ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
2643 | [] _ := forall₂.nil
id └┘ └─────────┘
src └┘ └─────────┘
typ └┘ └─────────┘
2644 | (a::as) h := forall₂.cons
id └┘ ┴ └──────────┘
src └┘ └──────────┘
typ └┘ ┴ └──────────┘
2645 (h _ (mem_cons_self _ _))
id └───────────┘
src └───────────┘
typ └───────────┘
2646 (forall₂_same $ assume a ha, h a $ mem_cons_of_mem _ ha)
id └──────────┘ ┴ └┘ ┴ └─────────────┘ └┘
src └─────────────┘
typ └──────────┘ ┴ └┘ ┴ └─────────────┘ └┘
2647
2648 lemma forall₂_refl {r} [is_refl α r] (l : list α) : forall₂ r l l :=
id └─────┘ ┴ ┴ └──┘ ┴ └─────┘ ┴ ┴ ┴
src └─────┘ └──┘ └─────┘
typ └─────┘ ┴ ┴ └──┘ ┴ └─────┘ ┴ ┴ ┴
2649 forall₂_same $ assume a h, is_refl.refl _ _
id └──────────┘ ┴ ┴ └──────────┘
src └──────────┘ └──────────┘
typ └──────────┘ ┴ ┴ └──────────┘
2650
2651 lemma forall₂_eq_eq_eq : forall₂ ((=) : α → α → Prop) = (=) :=
id └─────┘ ┴ ┴ ┴ ┴ ┴
src └─────┘ ┴ ┴ ┴
typ └─────┘ ┴ ┴ ┴ ┴ ┴
2652 begin
st └─────
2653 funext a b, apply propext,
id └─────┘
src └────────┘ └────┘└─────┘
typ └────────┘ └────┘└─────┘
doc └────────┘ └────┘
txt └────────┘ └────┘
par └────────┘ └────┘
pid └──┘ ┴
st ───────────┘└─────────────┘└─
2654 split,
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
st ──────┘└─
2655 { assume h, induction h, {refl}, simp only [*]; split; refl },
id ┴
src └──────┘ └────────┘ └──┘ └───────────┘ └───┘ └───┘
typ └──────┘ └────────┘┴ └──┘ └───────────┘ └───┘ └───┘
doc └──────┘ └────────┘ └──┘ └───────────┘ └───┘ └───┘
txt └──────┘ └────────┘ └──┘ └───────────┘ └───┘ └───┘
par └──────┘ └────────┘ └──┘ └───────────┘ └───┘ └───┘
pid └──────┘ ┴ ┴└──┘└──┘ ┴
st ───┘└──────┘└───────────┘└─────┘└┘└──────────────────────────┘└┘└
2656 { assume h, subst h, exact forall₂_refl _ }
id ┴ └──────────┘
src └──────┘ └────┘ └────┘└──────────┘└─┘
typ └──────┘ └────┘┴ └────┘└──────────┘└─┘
doc └──────┘ └────┘ └────┘ └─┘
txt └──────┘ └────┘ └────┘ └─┘
par └──────┘ └────┘ └────┘ └─┘
pid └──────┘ ┴ ┴ └┘┴
st ───────────┘└───────┘└─────────────────────┘└─
2657 end
st ──┘
2658
2659 @[simp] lemma forall₂_nil_left_iff {l} : forall₂ r nil l ↔ l = nil :=
id └─────┘ ┴ └─┘ ┴ ┴ ┴ ┴ └─┘
src └─────┘ └─┘ ┴ ┴ └─┘
typ └─────┘ ┴ └─┘ ┴ ┴ ┴ ┴ └─┘
doc └──┘
2660 ⟨λ H, by cases H; refl, by rintro rfl; exact forall₂.nil⟩
id ┴ ┴ └─────────┘
src └────┘ └──┘ └────────┘ └────┘└─────────┘
typ ┴ └────┘┴ └──┘ └────────┘ └────┘└─────────┘
doc └────┘ └──┘ └────────┘ └────┘
txt └────┘ └──┘ └────────┘ └────┘
par └────┘ └──┘ └────────┘ └────┘
pid ┴ └──┘ ┴
st └────────────┘ └────────────────────────────┘
2661
2662 @[simp] lemma forall₂_nil_right_iff {l} : forall₂ r l nil ↔ l = nil :=
id └─────┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘
src └─────┘ └─┘ ┴ ┴ └─┘
typ └─────┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘
doc └──┘
2663 ⟨λ H, by cases H; refl, by rintro rfl; exact forall₂.nil⟩
id ┴ ┴ └─────────┘
src └────┘ └──┘ └────────┘ └────┘└─────────┘
typ ┴ └────┘┴ └──┘ └────────┘ └────┘└─────────┘
doc └────┘ └──┘ └────────┘ └────┘
txt └────┘ └──┘ └────────┘ └────┘
par └────┘ └──┘ └────────┘ └────┘
pid ┴ └──┘ ┴
st └────────────┘ └────────────────────────────┘
2664
2665 lemma forall₂_cons_left_iff {a l u} : forall₂ r (a::l) u ↔ (∃b u', r a b ∧ forall₂ r l u' ∧ u = b :: u') :=
id └─────┘ ┴ ┴└┘┴ ┴ ┴ ┴┴ └┘┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └┘
src └─────┘ └┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └┘
typ └─────┘ ┴ ┴└┘┴ ┴ ┴ ┴┴ └┘┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ └┘
2666 iff.intro
id └───────┘
src └───────┘
typ └───────┘
2667 (assume h, match u, h with (b :: u'), forall₂.cons h₁ h₂ := ⟨b, u', h₁, h₂, rfl⟩ end)
id ┴ ┴ ┴ ┴ └┘ └┘ └──────────┘ └┘ └┘ └─┘
src └┘ └──────────┘ └─┘
typ ┴ ┴ ┴ ┴ └┘ └┘ └──────────┘ └┘ └┘ └─┘
2668 (assume h, match u, h with _, ⟨b, u', h₁, h₂, rfl⟩ := forall₂.cons h₁ h₂ end)
id ┴ ┴ ┴ └┘ └┘ └─┘ └──────────┘
src └─┘ └──────────┘
typ ┴ ┴ ┴ └┘ └┘ └─┘ └──────────┘
2669
2670 lemma forall₂_cons_right_iff {b l u} :
2671 forall₂ r u (b::l) ↔ (∃a u', r a b ∧ forall₂ r u' l ∧ u = a :: u') :=
id └─────┘ ┴ ┴ ┴└┘┴ ┴ ┴┴ └┘┴ ┴ ┴ ┴ ┴ └─────┘ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘ └┘
src └─────┘ └┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └┘
typ └─────┘ ┴ ┴ ┴└┘┴ ┴ ┴┴ └┘┴ ┴ ┴ ┴ ┴ └─────┘ ┴ └┘ ┴ ┴ ┴ ┴ ┴ └┘ └┘
2672 iff.intro
id └───────┘
src └───────┘
typ └───────┘
2673 (assume h, match u, h with (b :: u'), forall₂.cons h₁ h₂ := ⟨b, u', h₁, h₂, rfl⟩ end)
id ┴ ┴ ┴ ┴ └┘ └┘ └──────────┘ └┘ └┘ └─┘
src └┘ └──────────┘ └─┘
typ ┴ ┴ ┴ ┴ └┘ └┘ └──────────┘ └┘ └┘ └─┘
2674 (assume h, match u, h with _, ⟨b, u', h₁, h₂, rfl⟩ := forall₂.cons h₁ h₂ end)
id ┴ ┴ ┴ └┘ └┘ └─┘ └──────────┘
src └─┘ └──────────┘
typ ┴ ┴ ┴ └┘ └┘ └─┘ └──────────┘
2675
2676 lemma forall₂_and_left {r : α → β → Prop} {p : α → Prop} :
id ┴ ┴ ┴
typ ┴ ┴ ┴
2677 ∀l u, forall₂ (λa b, p a ∧ r a b) l u ↔ (∀a∈l, p a) ∧ forall₂ r l u
id ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
src └─────┘ ┴ ┴ ┴ └─────┘
typ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴
2678 | [] u := by simp only [forall₂_nil_left_iff, forall_prop_of_false (not_mem_nil _), imp_true_iff, true_and]
id └┘ └──────────────────┘ └──────────────────┘ └─────────┘ └──────────┘ └──────┘
src └┘ └─────────┘└──────────────────┘└┘└──────────────────┘┴ └─────────┘└───┘└──────────┘└┘└──────┘└┘
typ └┘ └─────────┘└──────────────────┘└┘└──────────────────┘┴ └─────────┘└───┘└──────────┘└┘└──────┘└┘
doc └─────────┘ └┘ ┴ └───┘ └┘ └┘
txt └─────────┘ └┘ ┴ └───┘ └┘ └┘
par └─────────┘ └┘ ┴ └───┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴ └───┘ └┘ ┴┴
st └──────────────────────────────────────────────────────────────────────────────────────────────┘
2679 | (a::l) u := by simp only [forall₂_and_left l, forall₂_cons_left_iff, forall_mem_cons,
id └┘ └──────────────┘ ┴ └───────────────────┘ └─────────────┘
src └┘ └─────────┘ ┴ └┘└───────────────────┘└┘└─────────────┘└─
typ └┘ └─────────┘└──────────────┘┴┴└┘└───────────────────┘└┘└─────────────┘└─
doc └─────────┘ ┴ └┘ └┘ └─
txt └─────────┘ ┴ └┘ └┘ └─
par └─────────┘ ┴ └┘ └┘ └─
pid ┴└──┘└┘ ┴ └┘ └┘ └─
st └───────────────────────────────────────────────────────────────────────
2680 and_assoc, and_comm, and.left_comm, exists_and_distrib_left.symm]
id └───────┘ └──────┘ └───────────┘
src ───┘└───────┘└┘└──────┘└┘└───────────┘└┘ └─
typ ───┘└───────┘└┘└──────┘└┘└───────────┘└┘└──────────────────────────┘└─
doc ───┘ └┘ └┘ └┘ └─
txt ───┘ └┘ └┘ └┘ └─
par ───┘ └┘ └┘ └┘ └─
pid ───┘ └┘ └┘ └┘ ┴└
st ──────────────────────────────────────────────────────────────────────
2681
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2682 @[simp] lemma forall₂_map_left_iff {f : γ → α} :
id ┴ ┴
typ ┴ ┴
doc └──┘
2683 ∀{l u}, forall₂ r (map f l) u ↔ forall₂ (λc b, r (f c) b) l u
id ┴┴ ┴ └─────┘ ┴ └─┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └─────┘ └─┘ ┴ └─────┘
typ ┴┴ ┴ └─────┘ ┴ └─┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
2684 | [] _ := by simp only [map, forall₂_nil_left_iff]
id └┘ └─┘ └──────────────────┘
src └┘ └─────────┘└─┘└┘└──────────────────┘└┘
typ └┘ └─────────┘└─┘└┘└──────────────────┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └─────────────────────────────────────┘
2685 | (a::l) _ := by simp only [map, forall₂_cons_left_iff, forall₂_map_left_iff]
id └┘ └─┘ └───────────────────┘
src └┘ └─────────┘└─┘└┘└───────────────────┘└┘ └─
typ └┘ └─────────┘└─┘└┘└───────────────────┘└┘└──────────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────
2686
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2687 @[simp] lemma forall₂_map_right_iff {f : γ → β} :
id ┴ ┴
typ ┴ ┴
doc └──┘
2688 ∀{l u}, forall₂ r l (map f u) ↔ forall₂ (λa c, r a (f c)) l u
id ┴┴ ┴ └─────┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └─────┘ └─┘ ┴ └─────┘
typ ┴┴ ┴ └─────┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
2689 | _ [] := by simp only [map, forall₂_nil_right_iff]
id └┘ └─┘ └───────────────────┘
src └┘ └─────────┘└─┘└┘└───────────────────┘└┘
typ └┘ └─────────┘└─┘└┘└───────────────────┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └──────────────────────────────────────┘
2690 | _ (b::u) := by simp only [map, forall₂_cons_right_iff, forall₂_map_right_iff]
id └┘ └─┘ └────────────────────┘
src └┘ └─────────┘└─┘└┘└────────────────────┘└┘ └─
typ └┘ └─────────┘└─┘└┘└────────────────────┘└┘└───────────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────────────────────
2691
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2692 lemma left_unique_forall₂ (hr : left_unique r) : left_unique (forall₂ r)
id └─────────┘ ┴ └─────────┘ └─────┘ ┴
src └─────────┘ └─────────┘ └─────┘
typ └─────────┘ ┴ └─────────┘ └─────┘ ┴
2693 | a₀ nil a₁ forall₂.nil forall₂.nil := rfl
id └─┘ └─────────┘ └─┘
src └─┘ └─────────┘ └─┘
typ └─┘ └─────────┘ └─┘
2694 | (a₀::l₀) (b::l) (a₁::l₁) (forall₂.cons ha₀ h₀) (forall₂.cons ha₁ h₁) :=
id └┘ └┘ └┘ └─┘ └┘ └──────────┘ └─┘ └┘
src └┘ └┘ └┘ └──────────┘
typ └┘ └┘ └┘ └─┘ └┘ └──────────┘ └─┘ └┘
2695 hr ha₀ ha₁ ▸ left_unique_forall₂ h₀ h₁ ▸ rfl
id └┘ ┴ └─────────────────┘ ┴ └─┘
src ┴ ┴ └─┘
typ └┘ ┴ └─────────────────┘ ┴ └─┘
2696
2697 lemma right_unique_forall₂ (hr : right_unique r) : right_unique (forall₂ r)
id └──────────┘ ┴ └──────────┘ └─────┘ ┴
src └──────────┘ └──────────┘ └─────┘
typ └──────────┘ ┴ └──────────┘ └─────┘ ┴
2698 | nil a₀ a₁ forall₂.nil forall₂.nil := rfl
id └─┘ └─────────┘ └─┘
src └─┘ └─────────┘ └─┘
typ └─┘ └─────────┘ └─┘
2699 | (b::l) (a₀::l₀) (a₁::l₁) (forall₂.cons ha₀ h₀) (forall₂.cons ha₁ h₁) :=
id └┘ └┘ └┘ └─┘ └┘ └──────────┘ └─┘ └┘
src └┘ └┘ └┘ └──────────┘
typ └┘ └┘ └┘ └─┘ └┘ └──────────┘ └─┘ └┘
2700 hr ha₀ ha₁ ▸ right_unique_forall₂ h₀ h₁ ▸ rfl
id └┘ ┴ └──────────────────┘ ┴ └─┘
src ┴ ┴ └─┘
typ └┘ ┴ └──────────────────┘ ┴ └─┘
2701
2702 lemma bi_unique_forall₂ (hr : bi_unique r) : bi_unique (forall₂ r) :=
id └───────┘ ┴ └───────┘ └─────┘ ┴
src └───────┘ └───────┘ └─────┘
typ └───────┘ ┴ └───────┘ └─────┘ ┴
2703 ⟨assume a b c, left_unique_forall₂ hr.1, assume a b c, right_unique_forall₂ hr.2⟩
id ┴ ┴ ┴ └─────────────────┘ └┘┴ ┴ ┴ ┴ └──────────────────┘ └┘┴
src └─────────────────┘ ┴ └──────────────────┘ ┴
typ ┴ ┴ ┴ └─────────────────┘ └┘┴ ┴ ┴ ┴ └──────────────────┘ └┘┴
2704
2705 theorem forall₂_length_eq {R : α → β → Prop} :
id ┴ ┴
typ ┴ ┴
2706 ∀ {l₁ l₂}, forall₂ R l₁ l₂ → length l₁ = length l₂
id ┴└┘ └┘ └─────┘ ┴ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘
src └─────┘ └────┘ ┴ └────┘
typ ┴└┘ └┘ └─────┘ ┴ └┘ └┘ └────┘ └┘ ┴ └────┘ └┘
2707 | _ _ forall₂.nil := rfl
id └─────────┘ └─┘
src └─────────┘ └─┘
typ └─────────┘ └─┘
2708 | _ _ (forall₂.cons h₁ h₂) := congr_arg succ (forall₂_length_eq h₂)
id └──────────┘ └┘ └───────┘ └──┘ └───────────────┘
src └──────────┘ └───────┘ └──┘
typ └──────────┘ └┘ └───────┘ └──┘ └───────────────┘
2709
2710 theorem forall₂_zip {R : α → β → Prop} :
id ┴ ┴
typ ┴ ┴
2711 ∀ {l₁ l₂}, forall₂ R l₁ l₂ → ∀ {a b}, (a, b) ∈ zip l₁ l₂ → R a b
id ┴└┘ └┘ └─────┘ ┴ └┘ └┘ ┴ ┴ ┴┴ ┴ ┴ └─┘ └┘ └┘ ┴ ┴ ┴
src └─────┘ ┴ ┴ └─┘
typ ┴└┘ └┘ └─────┘ ┴ └┘ └┘ ┴ ┴ ┴┴ ┴ ┴ └─┘ └┘ └┘ ┴ ┴ ┴
2712 | _ _ (forall₂.cons h₁ h₂) x y (or.inl rfl) := h₁
id └──────────┘ └┘ └────┘ └─┘
src └──────────┘ └────┘ └─┘
typ └──────────┘ └┘ └────┘ └─┘
2713 | _ _ (forall₂.cons h₁ h₂) x y (or.inr h₃) := forall₂_zip h₂ h₃
id └──────────┘ └┘ └────┘ └┘ └─────────┘
src └──────────┘ └────┘
typ └──────────┘ └┘ └────┘ └┘ └─────────┘
2714
2715 theorem forall₂_iff_zip {R : α → β → Prop} {l₁ l₂} : forall₂ R l₁ l₂ ↔
id ┴ ┴ └─────┘ ┴ └┘ └┘ ┴
src └─────┘ ┴
typ ┴ ┴ └─────┘ ┴ └┘ └┘ ┴
2716 length l₁ = length l₂ ∧ ∀ {a b}, (a, b) ∈ zip l₁ l₂ → R a b :=
id └────┘ └┘ ┴ └────┘ └┘ ┴ ┴ ┴ ┴┴ ┴ ┴ └─┘ └┘ └┘ ┴ ┴ ┴
src └────┘ ┴ └────┘ ┴ ┴ ┴ └─┘
typ └────┘ └┘ ┴ └────┘ └┘ ┴ ┴ ┴ ┴┴ ┴ ┴ └─┘ └┘ └┘ ┴ ┴ ┴
2717 ⟨λ h, ⟨forall₂_length_eq h, @forall₂_zip _ _ _ _ _ h⟩,
id ┴ └───────────────┘ ┴ └─────────┘ ┴
src └───────────────┘ └─────────┘
typ ┴ └───────────────┘ ┴ └─────────┘ ┴
2718 λ h, begin
id ┴
typ ┴
st └─────
2719 cases h with h₁ h₂,
id ┴
src └────┘ └─────────┘
typ └────┘┴└─────────┘
doc └────┘ └─────────┘
txt └────┘ └─────────┘
par └────┘ └─────────┘
pid ┴ └─────────┘
st ───────────────────┘└─
2720 induction l₁ with a l₁ IH generalizing l₂,
id └┘
src └────────┘ └───────────────────────────┘
typ └────────┘└┘└───────────────────────────┘
doc └────────┘ └───────────────────────────┘
txt └────────┘ └───────────────────────────┘
par └────────┘ └───────────────────────────┘
pid ┴ ┴└──────────┘└──────────────┘
st ──────────────────────────────────────────┘└─
2721 { cases length_eq_zero.1 h₁.symm, constructor },
id └────────────┘ └─────┘
src └────┘└────────────┘└─┘└─────┘ └──────────┘
typ └────┘└────────────┘└─┘└─────┘ └──────────┘
doc └────┘ └─┘ └──────────┘
txt └────┘ └─┘ └──────────┘
par └────┘ └─┘ └──────────┘
pid ┴ └─┘ ┴
st ───┘└────────────────────────────┘└────────────┘└┘└
2722 { cases l₂ with b l₂; injection h₁ with h₁,
id └┘ └┘
src └────┘ └────────┘ └────────┘ └──────┘
typ └────┘└┘└────────┘ └────────┘└┘└──────┘
doc └────┘ └────────┘ └────────┘ └──────┘
txt └────┘ └────────┘ └────────┘ └──────┘
par └────┘ └────────┘ └────────┘ └──────┘
pid ┴ └────────┘ ┴ └──────┘
st ───────────────────────────────────────────┘└─
2723 exact forall₂.cons (h₂ $ or.inl rfl) (IH h₁ $ λ a b h, h₂ $ or.inr h) }
id └──────────┘ └────┘ └─┘ └┘ └┘ └┘ └────┘
src └────┘└──────────┘┴ ┴ ┴└────┘┴└─┘└┘ ┴ ┴ ┴ └──────┘ ┴ ┴└────┘┴ └┘
typ └────┘└──────────┘┴ ┴ ┴└────┘┴└─┘└┘ └┘┴└┘┴ ┴ └──────┘└┘┴ ┴└────┘┴ └┘
doc └────┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └┘
txt └────┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └┘
par └────┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └┘
pid ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴┴
st ─────────────────────────────────────────────────────────────────────────┘└─
2724 end⟩
st ──┘
2725
2726 theorem forall₂_take {R : α → β → Prop} :
id ┴ ┴
typ ┴ ┴
2727 ∀ n {l₁ l₂}, forall₂ R l₁ l₂ → forall₂ R (take n l₁) (take n l₂)
id ┴ └┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └──┘ ┴ └┘ └──┘ ┴ └┘
src └─────┘ └─────┘ └──┘ └──┘
typ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └──┘ ┴ └┘ └──┘ ┴ └┘
2728 | 0 _ _ _ := by simp only [forall₂.nil, take]
id └─────────┘ └──┘
src └─────────┘└─────────┘└┘└──┘└┘
typ └─────────┘└─────────┘└┘└──┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └─────────────────────────────┘
2729 | (n+1) _ _ (forall₂.nil) := by simp only [forall₂.nil, take]
id ┴ └─────────┘ └─────────┘ └──┘
src ┴ └─────────┘ └─────────┘└─────────┘└┘└──┘└┘
typ ┴ └─────────┘ └─────────┘└─────────┘└┘└──┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └─────────────────────────────┘
2730 | (n+1) _ _ (forall₂.cons h₁ h₂) := by simp [and.intro h₁ h₂, forall₂_take n]
id ┴ └──────────┘ └───────┘ └┘ └┘ └──────────┘ ┴
src ┴ └──────────┘ └────┘└───────┘┴ ┴ └┘ ┴ └─
typ ┴ └──────────┘ └────┘└───────┘┴└┘┴└┘└┘└──────────┘┴┴└─
doc └────┘ ┴ ┴ └┘ ┴ └─
txt └────┘ ┴ ┴ └┘ ┴ └─
par └────┘ ┴ ┴ └┘ ┴ └─
pid ┴┴ ┴ ┴ └┘ ┴ ┴└
st └───────────────────────────────────────
2731
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2732 theorem forall₂_drop {R : α → β → Prop} :
id ┴ ┴
typ ┴ ┴
2733 ∀ n {l₁ l₂}, forall₂ R l₁ l₂ → forall₂ R (drop n l₁) (drop n l₂)
id ┴ └┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └──┘ ┴ └┘ └──┘ ┴ └┘
src └─────┘ └─────┘ └──┘ └──┘
typ ┴ └┘ └┘ └─────┘ ┴ └┘ └┘ └─────┘ ┴ └──┘ ┴ └┘ └──┘ ┴ └┘
2734 | 0 _ _ h := by simp only [drop, h]
id └──┘ ┴
src └─────────┘└──┘└┘ └┘
typ └─────────┘└──┘└┘┴└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └───────────────────┘
2735 | (n+1) _ _ (forall₂.nil) := by simp only [forall₂.nil, drop]
id ┴ └─────────┘ └─────────┘ └──┘
src ┴ └─────────┘ └─────────┘└─────────┘└┘└──┘└┘
typ ┴ └─────────┘ └─────────┘└─────────┘└┘└──┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └─────────────────────────────┘
2736 | (n+1) _ _ (forall₂.cons h₁ h₂) := by simp [and.intro h₁ h₂, forall₂_drop n]
id ┴ └──────────┘ └───────┘ └┘ └┘ └──────────┘ ┴
src ┴ └──────────┘ └────┘└───────┘┴ ┴ └┘ ┴ └─
typ ┴ └──────────┘ └────┘└───────┘┴└┘┴└┘└┘└──────────┘┴┴└─
doc └────┘ ┴ ┴ └┘ ┴ └─
txt └────┘ ┴ ┴ └┘ ┴ └─
par └────┘ ┴ ┴ └┘ ┴ └─
pid ┴┴ ┴ ┴ └┘ ┴ ┴└
st └───────────────────────────────────────
2737
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2738 theorem forall₂_take_append {R : α → β → Prop} (l : list α) (l₁ : list β) (l₂ : list β)
id ┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
2739 (h : forall₂ R l (l₁ ++ l₂)) : forall₂ R (list.take (length l₁) l) l₁ :=
id └─────┘ ┴ ┴ └┘ └┘ └┘ └─────┘ ┴ └───────┘ └────┘ └┘ ┴ └┘
src └─────┘ └┘ └─────┘ └───────┘ └────┘
typ └─────┘ ┴ ┴ └┘ └┘ └┘ └─────┘ ┴ └───────┘ └────┘ └┘ ┴ └┘
2740 have h': forall₂ R (take (length l₁) l) (take (length l₁) (l₁ ++ l₂)), from forall₂_take (length l₁) h,
id └─────┘ ┴ └──┘ └────┘ └┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ └──────────┘ └────┘ └┘ ┴
src └─────┘ └──┘ └────┘ └──┘ └────┘ └┘ └──────────┘ └────┘
typ └─────┘ ┴ └──┘ └────┘ └┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ └──────────┘ └────┘ └┘ ┴
2741 by rwa [take_left] at h'
id └───────┘
src └───┘└───────┘└───────
typ └───┘└───────┘└───────
doc └───┘ └───────
txt └───┘ └───────
par └───┘ └───────
pid └┘ ┴└────┘└
st └─────────────┘┴└──────
2742
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2743 theorem forall₂_drop_append {R : α → β → Prop} (l : list α) (l₁ : list β) (l₂ : list β)
id ┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴ └──┘ ┴
2744 (h : forall₂ R l (l₁ ++ l₂)) : forall₂ R (list.drop (length l₁) l) l₂ :=
id └─────┘ ┴ ┴ └┘ └┘ └┘ └─────┘ ┴ └───────┘ └────┘ └┘ ┴ └┘
src └─────┘ └┘ └─────┘ └───────┘ └────┘
typ └─────┘ ┴ ┴ └┘ └┘ └┘ └─────┘ ┴ └───────┘ └────┘ └┘ ┴ └┘
2745 have h': forall₂ R (drop (length l₁) l) (drop (length l₁) (l₁ ++ l₂)), from forall₂_drop (length l₁) h,
id └─────┘ ┴ └──┘ └────┘ └┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ └──────────┘ └────┘ └┘ ┴
src └─────┘ └──┘ └────┘ └──┘ └────┘ └┘ └──────────┘ └────┘
typ └─────┘ ┴ └──┘ └────┘ └┘ ┴ └──┘ └────┘ └┘ └┘ └┘ └┘ └──────────┘ └────┘ └┘ ┴
2746 by rwa [drop_left] at h'
id └───────┘
src └───┘└───────┘└───────
typ └───┘└───────┘└───────
doc └───┘ └───────
txt └───┘ └───────
par └───┘ └───────
pid └┘ ┴└────┘└
st └─────────────┘┴└──────
2747
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2748 lemma rel_mem (hr : bi_unique r) : (r ⇒ forall₂ r ⇒ iff) (∈) (∈)
id └───────┘ ┴ ┴ ┴ └─────┘ ┴ ┴ └─┘ ┴ ┴
src └───────┘ ┴ └─────┘ ┴ └─┘ ┴ ┴
typ └───────┘ ┴ ┴ ┴ └─────┘ ┴ ┴ └─┘ ┴ ┴
2749 | a b h [] [] forall₂.nil := by simp only [not_mem_nil]
id └┘ └┘ └─────────┘ └─────────┘
src └┘ └┘ └─────────┘ └─────────┘└─────────┘└┘
typ └┘ └┘ └─────────┘ └─────────┘└─────────┘└┘
doc └─────────┘ └┘
txt └─────────┘ └┘
par └─────────┘ └┘
pid ┴└──┘└┘ ┴┴
st └───────────────────────┘
2750 | a b h (a'::as) (b'::bs) (forall₂.cons h₁ h₂) := rel_or (rel_eq hr h h₁) (rel_mem h h₂)
id ┴ └┘ └┘ └──────────┘ └┘ └┘ └────┘ └────┘ └┘ └─────┘
src └┘ └┘ └──────────┘ └────┘ └────┘
typ ┴ └┘ └┘ └──────────┘ └┘ └┘ └────┘ └────┘ └┘ └─────┘
2751
2752 lemma rel_map : ((r ⇒ p) ⇒ forall₂ r ⇒ forall₂ p) map map
id ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └─┘ └─┘
src ┴ ┴ └─────┘ ┴ └─────┘ └─┘ └─┘
typ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └─┘ └─┘
2753 | f g h [] [] forall₂.nil := forall₂.nil
id └┘ └┘ └─────────┘ └─────────┘
src └┘ └┘ └─────────┘ └─────────┘
typ └┘ └┘ └─────────┘ └─────────┘
2754 | f g h (a::as) (b::bs) (forall₂.cons h₁ h₂) := forall₂.cons (h h₁) (rel_map @h h₂)
id ┴ └┘ └┘ └──────────┘ └┘ └┘ └──────────┘ └─────┘
src └┘ └┘ └──────────┘ └──────────┘
typ ┴ └┘ └┘ └──────────┘ └┘ └┘ └──────────┘ └─────┘
2755
2756 lemma rel_append : (forall₂ r ⇒ forall₂ r ⇒ forall₂ r) append append
id └─────┘ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └────┘ └────┘
src └─────┘ ┴ └─────┘ ┴ └─────┘ └────┘ └────┘
typ └─────┘ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └────┘ └────┘
2757 | [] [] h l₁ l₂ hl := hl
id └┘ └┘ └┘
src └┘ └┘
typ └┘ └┘ └┘
2758 | (a::as) (b::bs) (forall₂.cons h₁ h₂) l₁ l₂ hl := forall₂.cons h₁ (rel_append h₂ hl)
id └┘ └┘ └──────────┘ └┘ └┘ └┘ └──────────┘ └────────┘
src └┘ └┘ └──────────┘ └──────────┘
typ └┘ └┘ └──────────┘ └┘ └┘ └┘ └──────────┘ └────────┘
2759
2760 lemma rel_join : (forall₂ (forall₂ r) ⇒ forall₂ r) join join
id └─────┘ └─────┘ ┴ ┴ └─────┘ ┴ └──┘ └──┘
src └─────┘ └─────┘ ┴ └─────┘ └──┘ └──┘
typ └─────┘ └─────┘ ┴ ┴ └─────┘ ┴ └──┘ └──┘
2761 | [] [] forall₂.nil := forall₂.nil
id └┘ └┘ └─────────┘ └─────────┘
src └┘ └┘ └─────────┘ └─────────┘
typ └┘ └┘ └─────────┘ └─────────┘
2762 | (a::as) (b::bs) (forall₂.cons h₁ h₂) := rel_append h₁ (rel_join h₂)
id └┘ └┘ └──────────┘ └┘ └┘ └────────┘ └──────┘
src └┘ └┘ └──────────┘ └────────┘
typ └┘ └┘ └──────────┘ └┘ └┘ └────────┘ └──────┘
2763
2764 lemma rel_bind : (forall₂ r ⇒ (r ⇒ forall₂ p) ⇒ forall₂ p) list.bind list.bind :=
id └─────┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └───────┘ └───────┘
src └─────┘ ┴ ┴ └─────┘ ┴ └─────┘ └───────┘ └───────┘
typ └─────┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └───────┘ └───────┘
2765 assume a b h₁ f g h₂, rel_join (rel_map @h₂ h₁)
id ┴ ┴ └┘ ┴ ┴ └┘ └──────┘ └─────┘ └┘ └┘
src └──────┘ └─────┘
typ ┴ ┴ └┘ ┴ ┴ └┘ └──────┘ └─────┘ └┘ └┘
2766
2767 lemma rel_foldl : ((p ⇒ r ⇒ p) ⇒ p ⇒ forall₂ r ⇒ p) foldl foldl
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ └───┘ └───┘
src ┴ ┴ ┴ ┴ └─────┘ ┴ └───┘ └───┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ └───┘ └───┘
2768 | f g hfg _ _ h _ _ forall₂.nil := h
id ┴ └─────────┘
src └─────────┘
typ ┴ └─────────┘
2769 | f g hfg x y hxy _ _ (forall₂.cons hab hs) := rel_foldl @hfg (hfg hxy hab) hs
id └─┘ └─┘ └──────────┘ └─┘ └┘ └───────┘ └─┘
src └──────────┘
typ └─┘ └─┘ └──────────┘ └─┘ └┘ └───────┘ └─┘
2770
2771 lemma rel_foldr : ((r ⇒ p ⇒ p) ⇒ p ⇒ forall₂ r ⇒ p) foldr foldr
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ └───┘ └───┘
src ┴ ┴ ┴ ┴ └─────┘ ┴ └───┘ └───┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ └───┘ └───┘
2772 | f g hfg _ _ h _ _ forall₂.nil := h
id ┴ └─────────┘
src └─────────┘
typ ┴ └─────────┘
2773 | f g hfg x y hxy _ _ (forall₂.cons hab hs) := hfg hab (rel_foldr @hfg hxy hs)
id └─┘ └─┘ └──────────┘ └─┘ └┘ └───────┘
src └──────────┘
typ └─┘ └─┘ └──────────┘ └─┘ └┘ └───────┘
2774
2775 lemma rel_filter {p : α → Prop} {q : β → Prop} [decidable_pred p] [decidable_pred q]
id ┴ ┴ └────────────┘ ┴ └────────────┘ ┴
src └────────────┘ └────────────┘
typ ┴ ┴ └────────────┘ ┴ └────────────┘ ┴
2776 (hpq : (r ⇒ (↔)) p q) :
id ┴ ┴ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ ┴ ┴
2777 (forall₂ r ⇒ forall₂ r) (filter p) (filter q)
id └─────┘ ┴ ┴ └─────┘ ┴ └────┘ ┴ └────┘ ┴
src └─────┘ ┴ └─────┘ └────┘ └────┘
typ └─────┘ ┴ ┴ └─────┘ ┴ └────┘ ┴ └────┘ ┴
2778 | _ _ forall₂.nil := forall₂.nil
id └─────────┘ └─────────┘
src └─────────┘ └─────────┘
typ └─────────┘ └─────────┘
2779 | (a::as) (b::bs) (forall₂.cons h₁ h₂) :=
id └┘ └┘ └──────────┘
src └┘ └┘ └──────────┘
typ └┘ └┘ └──────────┘
2780 begin
st └─────
2781 by_cases p a,
id ┴ ┴
src └───────┘ ┴
typ └───────┘┴┴┴
doc └───────┘ ┴
txt └───────┘ ┴
par └───────┘ ┴
pid ┴ ┴
st ───────────────┘└─
2782 { have : q b, { rwa [← hpq h₁] },
id ┴ ┴ └─┘ └┘
src └─────┘ ┴ └─────┘ ┴ └┘
typ └─────┘┴┴┴ └─────┘└─┘┴└┘└┘
doc └─────┘ ┴ └─────┘ ┴ └┘
txt └─────┘ ┴ └─────┘ ┴ └┘
par └─────┘ ┴ └─────┘ ┴ └┘
pid └───┘└┘ ┴ └──┘ ┴ ┴┴
st ─────┘└────────┘└──┘└───────────┘┴┴└┘└
2783 simp only [filter_cons_of_pos _ h, filter_cons_of_pos _ this, forall₂_cons, h₁, rel_filter h₂, and_true], },
id └────────────────┘ ┴ └────────────────┘ └──┘ └──────────┘ └┘ └────────┘ └┘ └──────┘
src └─────────┘└────────────────┘└─┘ └┘└────────────────┘└─┘ └┘└──────────┘└┘ └┘ ┴ └┘└──────┘┴
typ └─────────┘└────────────────┘└─┘┴└┘└────────────────┘└─┘└──┘└┘└──────────┘└┘└┘└┘└────────┘┴└┘└┘└──────┘┴
doc └─────────┘ └─┘ └┘ └─┘ └┘ └┘ └┘ ┴ └┘ ┴
txt └─────────┘ └─┘ └┘ └─┘ └┘ └┘ └┘ ┴ └┘ ┴
par └─────────┘ └─┘ └┘ └─┘ └┘ └┘ └┘ ┴ └┘ ┴
pid ┴└──┘└┘ └─┘ └┘ └─┘ └┘ └┘ └┘ ┴ └┘ ┴
st ─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘└──┘└
2784 { have : ¬ q b, { rwa [← hpq h₁] },
id ┴ ┴ └─┘ └┘
src └─────┘ ┴ ┴ └─────┘ ┴ └┘
typ └─────┘ ┴┴┴┴ └─────┘└─┘┴└┘└┘
doc └─────┘ ┴ ┴ └─────┘ ┴ └┘
txt └─────┘ ┴ ┴ └─────┘ ┴ └┘
par └─────┘ ┴ ┴ └─────┘ ┴ └┘
pid └───┘└┘ ┴ ┴ └──┘ ┴ ┴┴
st ─────────────────┘└──┘└───────────┘┴┴└┘└
2785 simp only [filter_cons_of_neg _ h, filter_cons_of_neg _ this, rel_filter h₂], },
id └────────────────┘ ┴ └────────────────┘ └──┘ └────────┘ └┘
src └─────────┘└────────────────┘└─┘ └┘└────────────────┘└─┘ └┘ ┴ ┴
typ └─────────┘└────────────────┘└─┘┴└┘└────────────────┘└─┘└──┘└┘└────────┘┴└┘┴
doc └─────────┘ └─┘ └┘ └─┘ └┘ ┴ ┴
txt └─────────┘ └─┘ └┘ └─┘ └┘ ┴ ┴
par └─────────┘ └─┘ └┘ └─┘ └┘ ┴ ┴
pid ┴└──┘└┘ └─┘ └┘ └─┘ └┘ ┴ ┴
st ─────────────────────────────────────────────────────────────────────────────────┘└────
2786 end
st ────┘
2787
2788 theorem filter_map_cons (f : α → option β) (a : α) (l : list α) :
id ┴ └────┘ ┴ ┴ └──┘ ┴
src └────┘ └──┘
typ ┴ └────┘ ┴ ┴ └──┘ ┴
2789 filter_map f (a :: l) = option.cases_on (f a) (filter_map f l) (λb, b :: filter_map f l) :=
id └────────┘ ┴ ┴ └┘ ┴ ┴ └─────────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └┘ └────────┘ ┴ ┴
src └────────┘ └┘ ┴ └─────────────┘ └────────┘ └┘ └────────┘
typ └────────┘ ┴ ┴ └┘ ┴ ┴ └─────────────┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └┘ └────────┘ ┴ ┴
2790 begin
st └─────
2791 generalize eq : f a = b,
id ┴ ┴
src └──────────────┘ ┴ ┴ ┴
typ └──────────────┘┴┴┴┴ ┴
doc └──────────────┘ ┴ ┴ ┴
txt └──────────────┘ ┴ ┴ ┴
par └──────────────┘ ┴ ┴ ┴
pid └─┘└┘┴ ┴ ┴ ┴
st ────────────────────────┘└─
2792 cases b,
id ┴
src └────┘
typ └────┘┴
doc └────┘
txt └────┘
par └────┘
pid ┴
st ────────┘└─
2793 { rw filter_map_cons_none _ _ eq },
id └──────────────────┘ └┘
src └─┘└──────────────────┘└───┘└┘┴
typ └─┘└──────────────────┘└───┘└┘┴
doc └─┘ └───┘ ┴
txt └─┘ └───┘ ┴
par └─┘ └───┘ ┴
pid ┴ └───┘ ┴
st ───┘└─────────────────────────────┘└┘└
2794 { rw filter_map_cons_some _ _ _ eq },
id └──────────────────┘ └┘
src └─┘└──────────────────┘└─────┘└┘┴
typ └─┘└──────────────────┘└─────┘└┘┴
doc └─┘ └─────┘ ┴
txt └─┘ └─────┘ ┴
par └─┘ └─────┘ ┴
pid ┴ └─────┘ ┴
st ────────────────────────────────────┘└──
2795 end
st ──┘
2796
2797 lemma rel_filter_map : ((r ⇒ option.rel p) ⇒ forall₂ r ⇒ forall₂ p) filter_map filter_map
id ┴ ┴ └────────┘ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └────────┘ └────────┘
src ┴ └────────┘ ┴ └─────┘ ┴ └─────┘ └────────┘ └────────┘
typ ┴ ┴ └────────┘ ┴ ┴ └─────┘ ┴ ┴ └─────┘ ┴ └────────┘ └────────┘
2798 | f g hfg _ _ forall₂.nil := forall₂.nil
id └─────────┘ └─────────┘
src └─────────┘ └─────────┘
typ └─────────┘ └─────────┘
2799 | f g hfg (a::as) (b::bs) (forall₂.cons h₁ h₂) :=
id └┘ └┘ └──────────┘
src └┘ └┘ └──────────┘
typ └┘ └┘ └──────────┘
2800 by rw [filter_map_cons, filter_map_cons];
id └─────────────┘ └─────────────┘
src └──┘└─────────────┘└┘└─────────────┘┴
typ └──┘└─────────────┘└┘└─────────────┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st └──────────────────┘└───────────────┘┴└─
2801 from match f a, g b, hfg h₁ with
id ┴ ┴ ┴ ┴ └─┘ └┘
src └───┘ ┴ ┴ └┘ ┴ └┘ ┴ └─────
typ └───┘ ┴┴┴┴└┘┴┴┴└┘└─┘┴└┘└─────
doc └───┘ ┴ ┴ └┘ ┴ └┘ ┴ └─────
txt └───┘ ┴ ┴ └┘ ┴ └┘ ┴ └─────
par └───┘ ┴ ┴ └┘ ┴ └┘ ┴ └─────
pid └───┘ ┴ ┴ └┘ ┴ └┘ ┴ └─────
st ───────────────────────────────────
2802 | _, _, option.rel.none := rel_filter_map @hfg h₂
id └─────────────┘ └─┘
src ─────────┘└─────────────┘└──┘ ┴ ┴ └
typ ─────────┘└─────────────┘└──┘ ┴ └─┘┴ └
doc ─────────┘ └──┘ ┴ ┴ └
txt ─────────┘ └──┘ ┴ ┴ └
par ─────────┘ └──┘ ┴ ┴ └
pid ─────────┘ └──┘ ┴ ┴ └
st ────────────────────────────────────────────────────
2803 | _, _, option.rel.some h := forall₂.cons h (rel_filter_map @hfg h₂)
id └─────────────┘ ┴ └──────────┘ └────────────┘ └┘
src ─────────┘└─────────────┘┴ └──┘└──────────┘┴ ┴ ┴ ┴ └─
typ ─────────┘└─────────────┘┴┴└──┘└──────────┘┴ ┴ └────────────┘┴ ┴└┘└─
doc ─────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ └─
txt ─────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ └─
par ─────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ └─
pid ─────────┘ ┴ └──┘ ┴ ┴ ┴ ┴ └─
st ───────────────────────────────────────────────────────────────────────
2804 end
src ──────
typ ──────
doc ──────
txt ──────
par ──────
pid ────┘└
st ──────
2805
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2806 @[to_additive]
doc └─────────┘
2807 lemma rel_prod [monoid α] [monoid β]
id └────┘ ┴ └────┘ ┴
src └────┘ └────┘
typ └────┘ ┴ └────┘ ┴
2808 (h : r 1 1) (hf : (r ⇒ r ⇒ r) (*) (*)) : (forall₂ r ⇒ r) prod prod :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ └──┘ └──┘
src ┴ ┴ ┴ ┴ └─────┘ ┴ └──┘ └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ └──┘ └──┘
doc └──┘ └──┘
2809 rel_foldl hf h
id └───────┘ └┘ ┴
src └───────┘
typ └───────┘ └┘ ┴
2810
2811 end forall₂
2812
2813 /- sections -/
2814
2815 theorem mem_sections {L : list (list α)} {f} : f ∈ sections L ↔ forall₂ (∈) f L :=
id └──┘ └──┘ ┴ ┴ ┴ └──────┘ ┴ ┴ └─────┘ ┴ ┴ ┴
src └──┘ └──┘ ┴ └──────┘ ┴ └─────┘ ┴
typ └──┘ └──┘ ┴ ┴ ┴ └──────┘ ┴ ┴ └─────┘ ┴ ┴ ┴
doc └──────┘
2816 begin
st └─────
2817 refine ⟨λ h, _, λ h, _⟩,
src └─────┘ └─────┘ └────┘
typ └─────┘ └─────┘ └────┘
doc └─────┘ └─────┘ └────┘
txt └─────┘ └─────┘ └────┘
par └─────┘ └─────┘ └────┘
pid ┴ └─────┘ └────┘
st ────────────────────────┘└─
2818 { induction L generalizing f, {cases mem_singleton.1 h, exact forall₂.nil},
id ┴ └───────────┘ ┴ └─────────┘
src └────────┘ └─────────────┘ └────┘└───────────┘└─┘ └────┘└─────────┘
typ └────────┘┴└─────────────┘ └────┘└───────────┘└─┘┴ └────┘└─────────┘
doc └────────┘ └─────────────┘ └────┘ └─┘ └────┘
txt └────────┘ └─────────────┘ └────┘ └─┘ └────┘
par └────────┘ └─────────────┘ └────┘ └─┘ └────┘
pid ┴ ┴└────────────┘ ┴ └─┘ ┴
st ───┘└────────────────────────┘└────────────────────────┘└─────────────────┘└┘└
2819 simp only [sections, bind_eq_bind, mem_bind, mem_map] at h,
id └──────┘ └──────────┘ └──────┘ └─────┘
src └─────────┘└──────┘└┘└──────────┘└┘└──────┘└┘└─────┘└────┘
typ └─────────┘└──────┘└┘└──────────┘└┘└──────┘└┘└─────┘└────┘
doc └─────────┘└──────┘└┘ └┘ └┘ └────┘
txt └─────────┘ └┘ └┘ └┘ └────┘
par └─────────┘ └┘ └┘ └┘ └────┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴┴└──┘
st ─────────────────────────────────────────────────────────────┘└─
2820 rcases h with ⟨_, _, _, _, rfl⟩,
id ┴
src └─────┘ └─────────────────────┘
typ └─────┘┴└─────────────────────┘
doc └─────┘ └─────────────────────┘
txt └─────┘ └─────────────────────┘
par └─────┘ └─────────────────────┘
pid ┴ └─────────────────────┘
st ──────────────────────────────────┘└─
2821 simp only [*, forall₂_cons, true_and] },
id └──────────┘ └──────┘
src └────────────┘└──────────┘└┘└──────┘└┘
typ └────────────┘└──────────┘└┘└──────┘└┘
doc └────────────┘ └┘ └┘
txt └────────────┘ └┘ └┘
par └────────────┘ └┘ └┘
pid ┴└──┘└───┘ └┘ ┴┴
st ─────────────────────────────────────────┘└┘└
2822 { induction h with a l f L al fL fs, {exact or.inl rfl},
id ┴ └────┘ └─┘
src └────────┘ └────────────────────┘ └────┘└────┘┴└─┘
typ └────────┘┴└────────────────────┘ └────┘└────┘┴└─┘
doc └────────┘ └────────────────────┘ └────┘ ┴
txt └────────┘ └────────────────────┘ └────┘ ┴
par └────────┘ └────────────────────┘ └────┘ ┴
pid ┴ ┴└───────────────────┘ ┴ ┴
st ────────────────────────────────────┘└─────────────────┘└┘└
2823 simp only [sections, bind_eq_bind, mem_bind, mem_map],
id └──────┘ └──────────┘ └──────┘ └─────┘
src └─────────┘└──────┘└┘└──────────┘└┘└──────┘└┘└─────┘┴
typ └─────────┘└──────┘└┘└──────────┘└┘└──────┘└┘└─────┘┴
doc └─────────┘└──────┘└┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ ┴
st ────────────────────────────────────────────────────────┘└─
2824 exact ⟨_, fs, _, al, rfl, rfl⟩ }
id └┘ └┘ └─┘
src └────┘ └─┘ └───┘ └┘ └┘└─┘└┘
typ └────┘ └─┘└┘└───┘└┘└┘ └┘└─┘└┘
doc └────┘ └─┘ └───┘ └┘ └┘ └┘
txt └────┘ └─┘ └───┘ └┘ └┘ └┘
par └────┘ └─┘ └───┘ └┘ └┘ └┘
pid ┴ └─┘ └───┘ └┘ └┘ ┴┴
st ──────────────────────────────────┘└─
2825 end
st ──┘
2826
2827 theorem mem_sections_length {L : list (list α)} {f} (h : f ∈ sections L) : length f = length L :=
id └──┘ └──┘ ┴ ┴ ┴ └──────┘ ┴ └────┘ ┴ ┴ └────┘ ┴
src └──┘ └──┘ ┴ └──────┘ └────┘ ┴ └────┘
typ └──┘ └──┘ ┴ ┴ ┴ └──────┘ ┴ └────┘ ┴ ┴ └────┘ ┴
doc └──────┘
2828 forall₂_length_eq (mem_sections.1 h)
id └───────────────┘ └──────────┘┴ ┴
src └───────────────┘ └──────────┘┴
typ └───────────────┘ └──────────┘┴ ┴
2829
2830 lemma rel_sections {r : α → β → Prop} : (forall₂ (forall₂ r) ⇒ forall₂ (forall₂ r)) sections sections
id ┴ ┴ └─────┘ └─────┘ ┴ ┴ └─────┘ └─────┘ ┴ └──────┘ └──────┘
src └─────┘ └─────┘ ┴ └─────┘ └─────┘ └──────┘ └──────┘
typ ┴ ┴ └─────┘ └─────┘ ┴ ┴ └─────┘ └─────┘ ┴ └──────┘ └──────┘
doc └──────┘ └──────┘
2831 | _ _ forall₂.nil := forall₂.cons forall₂.nil forall₂.nil
id └─────────┘ └──────────┘ └─────────┘ └─────────┘
src └─────────┘ └──────────┘ └─────────┘ └─────────┘
typ └─────────┘ └──────────┘ └─────────┘ └─────────┘
2832 | _ _ (forall₂.cons h₀ h₁) :=
id └──────────┘ └┘ └┘
src └──────────┘
typ └──────────┘ └┘ └┘
2833 rel_bind (rel_sections h₁) (assume _ _ hl, rel_map (assume _ _ ha, forall₂.cons ha hl) h₀)
id └──────┘ └──────────┘ ┴ ┴ └┘ └─────┘ ┴ ┴ └┘ └──────────┘ └┘ └┘
src └──────┘ └─────┘ └──────────┘
typ └──────┘ └──────────┘ ┴ ┴ └┘ └─────┘ ┴ ┴ └┘ └──────────┘ └┘ └┘
2834
2835 /- permutations -/
2836
2837 section permutations
2838
2839 @[simp] theorem permutations_aux_nil (is : list α) : permutations_aux [] is = [] :=
id └──┘ ┴ └──────────────┘ └┘ └┘ ┴ └┘
src └──┘ └──────────────┘ └┘ ┴ └┘
typ └──┘ ┴ └──────────────┘ └┘ └┘ ┴ └┘
doc └──┘
2840 by rw [permutations_aux, permutations_aux.rec]
id └──────────────┘ └──────────────────┘
src └──┘└──────────────┘└┘└──────────────────┘└─
typ └──┘└──────────────┘└┘└──────────────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └───────────────────┘└────────────────────┘┴└
2841
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2842 @[simp] theorem permutations_aux_cons (t : α) (ts is : list α) :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
2843 permutations_aux (t :: ts) is = foldr (λy r, (permutations_aux2 t ts r y id).2)
id └──────────────┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ ┴ └───────────────┘ ┴ └┘ ┴ ┴ └┘ ┴
src └──────────────┘ └┘ ┴ └───┘ └───────────────┘ └┘ ┴
typ └──────────────┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ ┴ └───────────────┘ ┴ └┘ ┴ ┴ └┘ ┴
2844 (permutations_aux ts (t::is)) (permutations is) :=
id └──────────────┘ └┘ ┴└┘└┘ └──────────┘ └┘
src └──────────────┘ └┘ └──────────┘
typ └──────────────┘ └┘ ┴└┘└┘ └──────────┘ └┘
doc └──────────┘
2845 by rw [permutations_aux, permutations_aux.rec]; refl
id └──────────────┘ └──────────────────┘
src └──┘└──────────────┘└┘└──────────────────┘┴ └────
typ └──┘└──────────────┘└┘└──────────────────┘┴ └────
doc └──┘ └┘ ┴ └────
txt └──┘ └┘ ┴ └────
par └──┘ └┘ ┴ └────
pid └┘ └┘ ┴ └
st └───────────────────┘└────────────────────┘┴└──────
2846
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2847 end permutations
2848
2849 /- insert -/
2850 section insert
2851 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
2852
2853 @[simp] theorem insert_nil (a : α) : insert a nil = [a] := rfl
id ┴ └────┘ ┴ └─┘ ┴ ┴┴┴ └─┘
src └────┘ └─┘ ┴ ┴ ┴ └─┘
typ ┴ └────┘ ┴ └─┘ ┴ ┴┴┴ └─┘
doc └──┘
2854
2855 theorem insert.def (a : α) (l : list α) : insert a l = if a ∈ l then l else a :: l := rfl
id ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └─┘
src └──┘ └────┘ ┴ ┴ └┘ └─┘
typ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ └─┘
2856
2857 @[simp] theorem insert_of_mem {a : α} {l : list α} (h : a ∈ l) : insert a l = l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
doc └──┘
2858 by simp only [insert.def, if_pos h]
id └────────┘ └────┘ ┴
src └─────────┘└────────┘└┘└────┘┴ └─
typ └─────────┘└────────┘└┘└────┘┴┴└─
doc └─────────┘ └┘ ┴ └─
txt └─────────┘ └┘ ┴ └─
par └─────────┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ ┴ ┴└
st └─────────────────────────────────
2859
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2860 @[simp] theorem insert_of_not_mem {a : α} {l : list α} (h : a ∉ l) : insert a l = a :: l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴
src └──┘ ┴ └────┘ ┴ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ └┘ ┴
doc └──┘
2861 by simp only [insert.def, if_neg h]; split; refl
id └────────┘ └────┘ ┴
src └─────────┘└────────┘└┘└────┘┴ ┴ └───┘ └────
typ └─────────┘└────────┘└┘└────┘┴┴┴ └───┘ └────
doc └─────────┘ └┘ ┴ ┴ └───┘ └────
txt └─────────┘ └┘ ┴ ┴ └───┘ └────
par └─────────┘ └┘ ┴ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ ┴ ┴ └
st └──────────────────────────────────────────────
2862
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2863 @[simp] theorem mem_insert_iff {a b : α} {l : list α} : a ∈ insert b l ↔ a = b ∨ a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘
2864 begin
st └─────
2865 by_cases h' : b ∈ l,
id ┴ ┴ ┴
src └───────┘ └─┘ ┴┴┴
typ └───────┘ └─┘┴┴┴┴┴
doc └───────┘ └─┘ ┴ ┴
txt └───────┘ └─┘ ┴ ┴
par └───────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ────────────────────┘└─
2866 { simp only [insert_of_mem h'],
id └───────────┘ └┘
src └─────────┘└───────────┘┴ ┴
typ └─────────┘└───────────┘┴└┘┴
doc └─────────┘ ┴ ┴
txt └─────────┘ ┴ ┴
par └─────────┘ ┴ ┴
pid ┴└──┘└┘ ┴ ┴
st ───┘└──────────────────────────┘└─
2867 apply (or_iff_right_of_imp _).symm,
id └─────────────────┘
src └────┘ └─────────────────┘└──────┘
typ └────┘ └─────────────────┘└──────┘
doc └────┘ └──────┘
txt └────┘ └──────┘
par └────┘ └──────┘
pid ┴ └─────┘┴
st ─────────────────────────────────────┘└─
2868 exact λ e, e.symm ▸ h' },
id └───┘ ┴ └┘
src └────┘ └──┘ └───┘┴┴┴ ┴
typ └────┘ └──┘ └───┘┴┴┴└┘┴
doc └────┘ └──┘ ┴ ┴ ┴
txt └────┘ └──┘ ┴ ┴ ┴
par └────┘ └──┘ ┴ ┴ ┴
pid ┴ └──┘ ┴ ┴ ┴
st ──────────────────────────┘└┘└
2869 simp only [insert_of_not_mem h', mem_cons_iff]
id └───────────────┘ └┘ └──────────┘
src └─────────┘└───────────────┘┴ └┘└──────────┘└┘
typ └─────────┘└───────────────┘┴└┘└┘└──────────┘└┘
doc └─────────┘ ┴ └┘ └┘
txt └─────────┘ ┴ └┘ └┘
par └─────────┘ ┴ └┘ └┘
pid ┴└──┘└┘ ┴ └┘ ┴┴
st ────────────────────────────────────────────────┘
2870 end
st └─┘
2871
2872 @[simp] theorem suffix_insert (a : α) (l : list α) : l <:+ insert a l :=
id ┴ └──┘ ┴ ┴ └─┘ └────┘ ┴ ┴
src └──┘ └─┘ └────┘
typ ┴ └──┘ ┴ ┴ └─┘ └────┘ ┴ ┴
doc └──┘ └─┘
2873 by by_cases a ∈ l; [simp only [insert_of_mem h], simp only [insert_of_not_mem h, suffix_cons]]
id ┴ ┴ ┴ ┴ └───────────┘ ┴ └───────────────┘ ┴ └─────────┘
src └───────┘ ┴┴┴ ┴└─────────┘└───────────┘┴ ┴ └─────────┘└───────────────┘┴ └┘└─────────┘┴
typ └───────┘┴┴┴┴┴ ┴└─────────┘└───────────┘┴┴┴ └─────────┘└───────────────┘┴┴└┘└─────────┘┴
doc └───────┘ ┴ ┴ └─────────┘ ┴ ┴ └─────────┘ ┴ └┘ ┴
txt └───────┘ ┴ ┴ └─────────┘ ┴ ┴ └─────────┘ ┴ └┘ ┴
par └───────┘ ┴ ┴ └─────────┘ ┴ ┴ └─────────┘ ┴ └┘ ┴
pid ┴ ┴ ┴ ┴└──┘└┘ ┴ ┴ ┴└──┘└┘ ┴ └┘ ┴
st └──────────────────────────────────────────────────────────────────────────────────────────┘
2874
2875 @[simp] theorem mem_insert_self (a : α) (l : list α) : a ∈ insert a l :=
id ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴
src └──┘ ┴ └────┘
typ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴
doc └──┘
2876 mem_insert_iff.2 (or.inl rfl)
id └────────────┘┴ └────┘ └─┘
src └────────────┘┴ └────┘ └─┘
typ └────────────┘┴ └────┘ └─┘
2877
2878 @[simp] theorem mem_insert_of_mem {a b : α} {l : list α} (h : a ∈ l) : a ∈ insert b l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴
src └──┘ ┴ ┴ └────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴
doc └──┘
2879 mem_insert_iff.2 (or.inr h)
id └────────────┘┴ └────┘ ┴
src └────────────┘┴ └────┘
typ └────────────┘┴ └────┘ ┴
2880
2881 theorem eq_or_mem_of_mem_insert {a b : α} {l : list α} (h : a ∈ insert b l) : a = b ∨ a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
2882 mem_insert_iff.1 h
id └────────────┘┴ ┴
src └────────────┘┴
typ └────────────┘┴ ┴
2883
2884 @[simp] theorem length_insert_of_mem {a : α} {l : list α} (h : a ∈ l) :
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘
2885 length (insert a l) = length l :=
id └────┘ └────┘ ┴ ┴ ┴ └────┘ ┴
src └────┘ └────┘ ┴ └────┘
typ └────┘ └────┘ ┴ ┴ ┴ └────┘ ┴
2886 by rw insert_of_mem h
id └───────────┘ ┴
src └─┘└───────────┘┴ └
typ └─┘└───────────┘┴┴└
doc └─┘ ┴ └
txt └─┘ ┴ └
par └─┘ ┴ └
pid ┴ ┴ └
st └───────────────────
2887
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2888 @[simp] theorem length_insert_of_not_mem {a : α} {l : list α} (h : a ∉ l) :
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘
2889 length (insert a l) = length l + 1 :=
id └────┘ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
src └────┘ └────┘ ┴ └────┘ ┴
typ └────┘ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
2890 by rw insert_of_not_mem h; refl
id └───────────────┘ ┴
src └─┘└───────────────┘┴ └────
typ └─┘└───────────────┘┴┴ └────
doc └─┘ ┴ └────
txt └─┘ ┴ └────
par └─┘ ┴ └────
pid ┴ ┴ └
st └─────────────────────────────
2891
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2892 end insert
2893
2894 /- erasep -/
2895 section erasep
2896 variables {p : α → Prop} [decidable_pred p]
id └────────────┘
src └────────────┘
typ └────────────┘
2897
2898 @[simp] theorem erasep_nil : [].erasep p = [] := rfl
id └┘└────┘ ┴ ┴ └┘ └─┘
src └┘└────┘ ┴ └┘ └─┘
typ └┘└────┘ ┴ ┴ └┘ └─┘
doc └──┘
2899
2900 theorem erasep_cons (a : α) (l : list α) : (a :: l).erasep p = if p a then l else a :: l.erasep p := rfl
id ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴└─────┘ ┴ └─┘
src └──┘ └┘ └────┘ ┴ └┘ └─────┘ └─┘
typ ┴ └──┘ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴└─────┘ ┴ └─┘
2901
2902 @[simp] theorem erasep_cons_of_pos {a : α} {l : list α} (h : p a) : (a :: l).erasep p = l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ ┴
src └──┘ └┘ └────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ ┴
doc └──┘
2903 by simp [erasep_cons, h]
id └─────────┘ ┴
src └────┘└─────────┘└┘ └─
typ └────┘└─────────┘└┘┴└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid ┴┴ └┘ ┴└
st └──────────────────────
2904
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2905 @[simp] theorem erasep_cons_of_neg {a : α} {l : list α} (h : ¬ p a) : (a::l).erasep p = a :: l.erasep p :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴└┘┴ └────┘ ┴ ┴ ┴ └┘ ┴└─────┘ ┴
src └──┘ ┴ └┘ └────┘ ┴ └┘ └─────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴└┘┴ └────┘ ┴ ┴ ┴ └┘ ┴└─────┘ ┴
doc └──┘
2906 by simp [erasep_cons, h]
id └─────────┘ ┴
src └────┘└─────────┘└┘ └─
typ └────┘└─────────┘└┘┴└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid ┴┴ └┘ ┴└
st └──────────────────────
2907
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2908 theorem erasep_of_forall_not {l : list α}
id └──┘ ┴
src └──┘
typ └──┘ ┴
2909 (h : ∀ a ∈ l, ¬ p a) : l.erasep p = l :=
id ┴ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴
src ┴ └─────┘ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴
2910 by induction l with _ _ ih; [refl,
id ┴ ┴
src └────────┘ └──────────┘ ┴└──┘
typ └────────┘┴└──────────┘ ┴└──┘
doc └────────┘ └──────────┘ └──┘
txt └────────┘ └──────────┘ └──┘
par └────────┘ └──────────┘ └──┘
pid ┴ ┴└─────────┘
st └────────────────────────────────
2911 simp [h _ (or.inl rfl), ih (forall_mem_of_forall_mem_cons h)]]
id ┴ └────┘ └─┘ └┘ └───────────────────────────┘ ┴
src └────┘ └─┘ └────┘┴└─┘└─┘ ┴ └───────────────────────────┘┴ └┘
typ └────┘┴└─┘ └────┘┴└─┘└─┘└┘┴ └───────────────────────────┘┴┴└┘
doc └────┘ └─┘ ┴ └─┘ ┴ ┴ └┘
txt └────┘ └─┘ ┴ └─┘ ┴ ┴ └┘
par └────┘ └─┘ ┴ └─┘ ┴ ┴ └┘
pid ┴┴ └─┘ ┴ └─┘ ┴ ┴ └┘
st ───────────────────────────────────────────────────────────────┘
2912
2913 theorem exists_of_erasep {l : list α} {a} (al : a ∈ l) (pa : p a) :
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
2914 ∃ a l₁ l₂, (∀ b ∈ l₁, ¬ p b) ∧ p a ∧ l = l₁ ++ a :: l₂ ∧ l.erasep p = l₁ ++ l₂ :=
id ┴ ┴ └┘ └┘┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴└─────┘ ┴ ┴ └┘ └┘ └┘
src ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └─────┘ ┴ └┘
typ ┴ ┴ └┘ └┘┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴└─────┘ ┴ ┴ └┘ └┘ └┘
2915 begin
st └─────
2916 induction l with b l IH, {cases al},
id ┴ └┘
src └────────┘ └──────────┘ └────┘
typ └────────┘┴└──────────┘ └────┘└┘
doc └────────┘ └──────────┘ └────┘
txt └────────┘ └──────────┘ └────┘
par └────────┘ └──────────┘ └────┘
pid ┴ ┴└─────────┘ ┴
st ────────────────────────┘└─────────┘└┘└
2917 by_cases pb : p b,
id ┴ ┴
src └───────┘ └─┘ ┴
typ └───────┘ └─┘┴┴┴
doc └───────┘ └─┘ ┴
txt └───────┘ └─┘ ┴
par └───────┘ └─┘ ┴
pid ┴ └─┘ ┴
st ──────────────────┘└─
2918 { exact ⟨b, [], l, forall_mem_nil _, pb, by simp [pb]⟩ },
id ┴ ┴ └────────────┘ └┘ └┘
src └────┘ └┘ └┘ └┘└────────────┘└──┘ └┘ ┴└────┘ ┴└┘
typ └────┘ ┴└┘ └┘┴└┘└────────────┘└──┘└┘└┘ ┴└────┘└┘┴└┘
doc └────┘ └┘ └┘ └┘ └──┘ └┘ ┴└────┘ ┴└┘
txt └────┘ └┘ └┘ └┘ └──┘ └┘ ┴└────┘ ┴└┘
par └────┘ └┘ └┘ └┘ └──┘ └┘ ┴└────┘ ┴└┘
pid ┴ └┘ └┘ └┘ └──┘ └┘ └─────┘ └┘┴
st ───┘└───────────────────────────────────────┘└────────┘└┘└┘└
2919 { rcases al with rfl | al, {exact pb.elim pa},
id └┘ └─────┘ └┘
src └─────┘ └────────────┘ └────┘└─────┘┴
typ └─────┘└┘└────────────┘ └────┘└─────┘┴└┘
doc └─────┘ └────────────┘ └────┘ ┴
txt └─────┘ └────────────┘ └────┘ ┴
par └─────┘ └────────────┘ └────┘ ┴
pid ┴ └────────────┘ ┴ ┴
st ──────────────────────────┘└─────────────────┘└┘└
2920 rcases IH al with ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩,
id └┘ └┘
src └─────┘ ┴ └───────────────────────────────┘
typ └─────┘└┘┴└┘└───────────────────────────────┘
doc └─────┘ ┴ └───────────────────────────────┘
txt └─────┘ ┴ └───────────────────────────────┘
par └─────┘ ┴ └───────────────────────────────┘
pid ┴ ┴ └───────────────────────────────┘
st ────────────────────────────────────────────────┘└─
2921 exact ⟨c, b::l₁, l₂, forall_mem_cons.2 ⟨pb, h₁⟩,
id ┴ ┴ └┘ └┘ └─────────────┘ └┘ └┘
src └────┘ └┘ └┘ └┘└─────────────┘└─┘ └┘ └──
typ └────┘ ┴└┘┴ └┘└┘└┘└┘└─────────────┘└─┘ └┘└┘└┘└──
doc └────┘ └┘ └┘ └┘ └─┘ └┘ └──
txt └────┘ └┘ └┘ └┘ └─┘ └┘ └──
par └────┘ └┘ └┘ └┘ └─┘ └┘ └──
pid ┴ └┘ └┘ └┘ └─┘ └┘ └──
st ─────────────────────────────────────────────────────
2922 h₂, by rw h₃; refl, by simp [pb, h₄]⟩ }
id └┘ └┘ └┘ └┘
src ─────┘ └┘ ┴└─┘ └┘└──┘└┘ ┴└────┘ └┘ ┴└┘
typ ─────┘└┘└┘ ┴└─┘└┘└┘└──┘└┘ ┴└────┘└┘└┘└┘┴└┘
doc ─────┘ └┘ ┴└─┘ └┘└──┘└┘ ┴└────┘ └┘ ┴└┘
txt ─────┘ └┘ ┴└─┘ └┘└──┘└┘ ┴└────┘ └┘ ┴└┘
par ─────┘ └┘ ┴└─┘ └┘└──┘└┘ ┴└────┘ └┘ ┴└┘
pid ─────┘ └┘ └──┘ └──────┘ └─────┘ └┘ └┘┴
st ───────────┘└──────────┘└──┘└────────────┘└┘└─
2923 end
st ──┘
2924
2925 theorem exists_or_eq_self_of_erasep (p : α → Prop) [decidable_pred p] (l : list α) :
id ┴ └────────────┘ ┴ └──┘ ┴
src └────────────┘ └──┘
typ ┴ └────────────┘ ┴ └──┘ ┴
2926 l.erasep p = l ∨ ∃ a l₁ l₂, (∀ b ∈ l₁, ¬ p b) ∧ p a ∧ l = l₁ ++ a :: l₂ ∧ l.erasep p = l₁ ++ l₂ :=
id ┴└─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴└─────┘ ┴ ┴ └┘ └┘ └┘
src └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └─────┘ ┴ └┘
typ ┴└─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴└─────┘ ┴ ┴ └┘ └┘ └┘
2927 begin
st └─────
2928 by_cases h : ∃ a ∈ l, p a,
id ┴ ┴┴ ┴
src └───────┘ └─┘┴└───┘ ┴┴ ┴
typ └───────┘ └─┘┴└───┘┴┴┴┴┴
doc └───────┘ └─┘ └───┘ ┴ ┴
txt └───────┘ └─┘ └───┘ ┴ ┴
par └───────┘ └─┘ └───┘ ┴ ┴
pid ┴ └─┘ └───┘ ┴ ┴
st ──────────────────────────┘└─
2929 { rcases h with ⟨a, ha, pa⟩,
id ┴
src └─────┘ └───────────────┘
typ └─────┘┴└───────────────┘
doc └─────┘ └───────────────┘
txt └─────┘ └───────────────┘
par └─────┘ └───────────────┘
pid ┴ └───────────────┘
st ───┘└───────────────────────┘└─
2930 exact or.inr (exists_of_erasep ha pa) },
id └────┘ └──────────────┘ └┘ └┘
src └────┘└────┘┴ └──────────────┘┴ ┴ └┘
typ └────┘└────┘┴ └──────────────┘┴└┘┴└┘└┘
doc └────┘ ┴ ┴ ┴ └┘
txt └────┘ ┴ ┴ ┴ └┘
par └────┘ ┴ ┴ ┴ └┘
pid ┴ ┴ ┴ ┴ ┴┴
st ─────────────────────────────────────────┘└┘└
2931 { simp at h, exact or.inl (erasep_of_forall_not h) }
id └────┘ └──────────────────┘ ┴
src └───────┘ └────┘└────┘┴ └──────────────────┘┴ └┘
typ └───────┘ └────┘└────┘┴ └──────────────────┘┴┴└┘
doc └───────┘ └────┘ ┴ ┴ └┘
txt └───────┘ └────┘ ┴ ┴ └┘
par └───────┘ └────┘ ┴ ┴ └┘
pid ┴└──┘ ┴ ┴ ┴ ┴┴
st ────────────┘└──────────────────────────────────────┘└─
2932 end
st ──┘
2933
2934 @[simp] theorem length_erasep_of_mem {l : list α} {a} (al : a ∈ l) (pa : p a) :
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘
2935 length (l.erasep p) = pred (length l) :=
id └────┘ ┴└─────┘ ┴ ┴ └──┘ └────┘ ┴
src └────┘ └─────┘ ┴ └──┘ └────┘
typ └────┘ ┴└─────┘ ┴ ┴ └──┘ └────┘ ┴
2936 by rcases exists_of_erasep al pa with ⟨_, l₁, l₂, _, _, e₁, e₂⟩;
id └──────────────┘ └┘ └┘
src └─────┘└──────────────┘┴ ┴ └─────────────────────────────┘
typ └─────┘└──────────────┘┴└┘┴└┘└─────────────────────────────┘
doc └─────┘ ┴ ┴ └─────────────────────────────┘
txt └─────┘ ┴ ┴ └─────────────────────────────┘
par └─────┘ ┴ ┴ └─────────────────────────────┘
pid ┴ ┴ ┴ └─────────────────────────────┘
st └──────────────────────────────────────────────────────────────
2937 rw e₂; simp [-add_comm, e₁]; refl
id └┘ └┘
src └─┘ └───────────────┘ ┴ └────
typ └─┘└┘ └───────────────┘└┘┴ └────
doc └─┘ └───────────────┘ ┴ └────
txt └─┘ └───────────────┘ ┴ └────
par └─┘ └───────────────┘ ┴ └────
pid ┴ ┴└──────────┘ ┴ └
st ─────┘└┘└────────────────────────────
2938
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2939 theorem erasep_append_left {a : α} (pa : p a) :
id ┴ ┴ ┴
typ ┴ ┴ ┴
2940 ∀ {l₁ : list α} (l₂), a ∈ l₁ → (l₁++l₂).erasep p = l₁.erasep p ++ l₂
id ┴ └──┘ ┴ └┘ ┴ ┴ └┘ └┘└┘└┘ └────┘ ┴ ┴ └┘└─────┘ ┴ └┘ └┘
src └──┘ ┴ └┘ └────┘ ┴ └─────┘ └┘
typ ┴ └──┘ ┴ └┘ ┴ ┴ └┘ └┘└┘└┘ └────┘ ┴ ┴ └┘└─────┘ ┴ └┘ └┘
2941 | (x::xs) l₂ h := begin
id └┘
src └┘
typ └┘
st └─────
2942 by_cases h' : p x; simp [h'],
id ┴ ┴ └┘
src └───────┘ └─┘ ┴ └────┘ ┴
typ └───────┘ └─┘┴┴┴ └────┘└┘┴
doc └───────┘ └─┘ ┴ └────┘ ┴
txt └───────┘ └─┘ ┴ └────┘ ┴
par └───────┘ └─┘ ┴ └────┘ ┴
pid ┴ └─┘ ┴ ┴┴ ┴
st ─────────────────────────────┘└─
2943 rw erasep_append_left l₂ (mem_of_ne_of_mem (mt _ h') h),
id └────────────────┘ └┘ └──────────────┘ └┘ └┘ ┴
src └─┘ ┴ ┴ └──────────────┘┴ └┘└─┘ └┘ ┴
typ └─┘└────────────────┘┴└┘┴ └──────────────┘┴ └┘└─┘└┘└┘┴┴
doc └─┘ ┴ ┴ ┴ └─┘ └┘ ┴
txt └─┘ ┴ ┴ ┴ └─┘ └┘ ┴
par └─┘ ┴ ┴ ┴ └─┘ └┘ ┴
pid ┴ ┴ ┴ ┴ └─┘ └┘ ┴
st ────────────────────────────────────────────────────────┘└─
2944 rintro rfl, exact pa
id └┘
src └────────┘ └────┘ ┴
typ └────────┘ └────┘└┘┴
doc └────────┘ └────┘ ┴
txt └────────┘ └────┘ ┴
par └────────┘ └────┘ ┴
pid └──┘ ┴ ┴
st ───────────┘└─────────┘
2945 end
st └─┘
2946
2947 theorem erasep_append_right : ∀ {l₁ : list α} (l₂), (∀ b ∈ l₁, ¬ p b) → (l₁++l₂).erasep p = l₁ ++ l₂.erasep p
id ┴ └──┘ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘└┘└┘ └────┘ ┴ ┴ └┘ └┘ └┘└─────┘ ┴
src └──┘ ┴ └┘ └────┘ ┴ └┘ └─────┘
typ ┴ └──┘ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘└┘└┘ └────┘ ┴ ┴ └┘ └┘ └┘└─────┘ ┴
2948 | [] l₂ h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2949 | (x::xs) l₂ h := by simp [(forall_mem_cons.1 h).1,
id └┘ └─────────────┘ ┴
src └┘ └────┘ └─────────────┘└─┘ └────
typ └┘ └────┘ └─────────────┘└─┘┴└────
doc └────┘ └─┘ └────
txt └────┘ └─┘ └────
par └────┘ └─┘ └────
pid ┴┴ └─┘ └────
st └───────────────────────────────
2950 erasep_append_right _ (forall_mem_cons.1 h).2]
id └─────────────────┘ └─────────────┘ ┴
src ─┘ └─┘ └─────────────┘└─┘ └────
typ ─┘└─────────────────┘└─┘ └─────────────┘└─┘┴└────
doc ─┘ └─┘ └─┘ └────
txt ─┘ └─┘ └─┘ └────
par ─┘ └─┘ └─┘ └────
pid ─┘ └─┘ └─┘ └──┘└
st ─────────────────────────────────────────────────
2951
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2952 theorem erasep_sublist (l : list α) : l.erasep p <+ l :=
id └──┘ ┴ ┴└─────┘ ┴ └┘ ┴
src └──┘ └─────┘ └┘
typ └──┘ ┴ ┴└─────┘ ┴ └┘ ┴
2953 by rcases exists_or_eq_self_of_erasep p l with h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩;
id └─────────────────────────┘ ┴ ┴
src └─────┘└─────────────────────────┘┴ ┴ └───────────────────────────────────┘
typ └─────┘└─────────────────────────┘┴┴┴┴└───────────────────────────────────┘
doc └─────┘ ┴ ┴ └───────────────────────────────────┘
txt └─────┘ ┴ ┴ └───────────────────────────────────┘
par └─────┘ ┴ ┴ └───────────────────────────────────┘
pid ┴ ┴ ┴ └───────────────────────────────────┘
st └─────────────────────────────────────────────────────────────────────────────
2954 [rw h, {rw [h₄, h₃], simp}]
id ┴ ┴ └┘ └┘
src ┴└─┘ └──┘ └┘ ┴ └──┘
typ ┴└─┘┴ └──┘└┘└┘└┘┴ └──┘
doc └─┘ └──┘ └┘ ┴ └──┘
txt └─┘ └──┘ └┘ ┴ └──┘
par └─┘ └──┘ └┘ ┴ └──┘
pid ┴ └┘ └┘ ┴
st ──────┘┴└┘└─────┘└──┘└─────┘└┘
2955
2956 theorem erasep_subset (l : list α) : l.erasep p ⊆ l :=
id └──┘ ┴ ┴└─────┘ ┴ ┴ ┴
src └──┘ └─────┘ ┴
typ └──┘ ┴ ┴└─────┘ ┴ ┴ ┴
2957 subset_of_sublist (erasep_sublist l)
id └───────────────┘ └────────────┘ ┴
src └───────────────┘ └────────────┘
typ └───────────────┘ └────────────┘ ┴
2958
2959 theorem erasep_sublist_erasep {l₁ l₂ : list α} (s : l₁ <+ l₂) : l₁.erasep p <+ l₂.erasep p :=
id └──┘ ┴ └┘ └┘ └┘ └┘└─────┘ ┴ └┘ └┘└─────┘ ┴
src └──┘ └┘ └─────┘ └┘ └─────┘
typ └──┘ ┴ └┘ └┘ └┘ └┘└─────┘ ┴ └┘ └┘└─────┘ ┴
2960 begin
st └─────
2961 induction s,
id ┴
src └────────┘
typ └────────┘┴
doc └────────┘
txt └────────┘
par └────────┘
pid ┴
st ────────────┘└─
2962 case list.sublist.slnil { refl },
src └────────────────────────┘└───┘┴
typ └────────────────────────┘└───┘┴
doc └────────────────────────┘└───┘┴
txt └────────────────────────┘└───┘┴
par └────────────────────────┘└───┘┴
pid └─────────────────┘┴└──────┘
st ──────────────────────────┘└────┘└┘└
2963 case list.sublist.cons : l₁ l₂ a s IH {
src └───────────────────────────────────────
typ └───────────────────────────────────────
doc └───────────────────────────────────────
txt └───────────────────────────────────────
par └───────────────────────────────────────
pid └────────────────┘└─────────────┘└──
st ────────────────────────────────────────┘└
2964 by_cases h : p a; simp [h],
id ┴ ┴ ┴
src ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
typ ───┘└───────┘ └─┘┴┴┴└┘└────┘┴┴└─
doc ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
txt ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
par ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
pid ────────────┘ └─┘ ┴ └──────┘ └──
st ─────────────────────────────┘└─
2965 exacts [IH.trans (erasep_sublist _), IH.cons _ _ _] },
id └──────┘ └────────────┘ └─────┘
src ───┘└──────┘└──────┘┴ └────────────┘└───┘└─────┘└──────┘┴
typ ───┘└──────┘└──────┘┴ └────────────┘└───┘└─────┘└──────┘┴
doc ───┘└──────┘ ┴ └───┘ └──────┘┴
txt ───┘└──────┘ ┴ └───┘ └──────┘┴
par ───┘└──────┘ ┴ └───┘ └──────┘┴
pid ───────────┘ ┴ └───┘ └───────┘
st ───────────────────────────────────────────────────────┘└┘└
2966 case list.sublist.cons2 : l₁ l₂ a s IH {
src └────────────────────────────────────────
typ └────────────────────────────────────────
doc └────────────────────────────────────────
txt └────────────────────────────────────────
par └────────────────────────────────────────
pid └─────────────────┘└─────────────┘└──
st ─────────────────────────────────────────┘└
2967 by_cases h : p a; simp [h],
id ┴ ┴ ┴
src ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
typ ───┘└───────┘ └─┘┴┴┴└┘└────┘┴┴└─
doc ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
txt ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
par ───┘└───────┘ └─┘ ┴ └┘└────┘ ┴└─
pid ────────────┘ └─┘ ┴ └──────┘ └──
st ─────────────────────────────┘└─
2968 exacts [s, IH.cons2 _ _ _] }
id ┴ └──────┘
src ───┘└──────┘ └┘└──────┘└──────┘└┘
typ ───┘└──────┘┴└┘└──────┘└──────┘└┘
doc ───┘└──────┘ └┘ └──────┘└┘
txt ───┘└──────┘ └┘ └──────┘└┘
par ───┘└──────┘ └┘ └──────┘└┘
pid ───────────┘ └┘ └───────┘┴
st ──────────────────────────────┘┴┴
2969 end
st └─┘
2970
2971 theorem mem_of_mem_erasep {a : α} {l : list α} : a ∈ l.erasep p → a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └─────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴ ┴
2972 @erasep_subset _ _ _ _ _
id └───────────┘
src └───────────┘
typ └───────────┘
2973
2974 @[simp] theorem mem_erasep_of_neg {a : α} {l : list α} (pa : ¬ p a) : a ∈ l.erasep p ↔ a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ └─────┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘
2975 ⟨mem_of_mem_erasep, λ al, begin
id └───────────────┘ └┘
src └───────────────┘
typ └───────────────┘ └┘
st └─────
2976 rcases exists_or_eq_self_of_erasep p l with h | ⟨c, l₁, l₂, h₁, h₂, h₃, h₄⟩,
id └─────────────────────────┘ ┴ ┴
src └─────┘└─────────────────────────┘┴ ┴ └───────────────────────────────────┘
typ └─────┘└─────────────────────────┘┴┴┴┴└───────────────────────────────────┘
doc └─────┘ ┴ ┴ └───────────────────────────────────┘
txt └─────┘ ┴ ┴ └───────────────────────────────────┘
par └─────┘ ┴ ┴ └───────────────────────────────────┘
pid ┴ ┴ ┴ └───────────────────────────────────┘
st ────────────────────────────────────────────────────────────────────────────┘└─
2977 { rwa h },
id ┴
src └──┘ ┴
typ └──┘┴┴
doc └──┘ ┴
txt └──┘ ┴
par └──┘ ┴
pid ┴ ┴
st ───┘└────┘└┘└
2978 { rw h₄, rw h₃ at al,
id └┘ └┘
src └─┘ └─┘ └────┘
typ └─┘└┘ └─┘└┘└────┘
doc └─┘ └─┘ └────┘
txt └─┘ └─┘ └────┘
par └─┘ └─┘ └────┘
pid ┴ ┴ └────┘
st ────────┘└───────────┘└─
2979 have : a ≠ c, {rintro rfl, exact pa.elim h₂},
id ┴ ┴ ┴ └─────┘ └┘
src └─────┘ ┴┴┴ └────────┘ └────┘└─────┘┴
typ └─────┘┴┴┴┴┴ └────────┘ └────┘└─────┘┴└┘
doc └─────┘ ┴ ┴ └────────┘ └────┘ ┴
txt └─────┘ ┴ ┴ └────────┘ └────┘ ┴
par └─────┘ ┴ ┴ └────────┘ └────┘ ┴
pid └───┘└┘ ┴ ┴ └──┘ ┴ ┴
st ───────────────┘└───────────┘└────────────────┘└┘└
2980 simpa [this] using al }
id └──┘ └┘
src └─────┘ └──────┘ ┴
typ └─────┘└──┘└──────┘└┘┴
doc └─────┘ └──────┘ ┴
txt └─────┘ └──────┘ ┴
par └─────┘ └──────┘ ┴
pid ┴┴ ┴┴└────┘ ┴
st ─────────────────────────┘└─
2981 end⟩
st ──┘
2982
2983 theorem erasep_map (f : β → α) :
id ┴ ┴
typ ┴ ┴
2984 ∀ (l : list β), (map f l).erasep p = map f (l.erasep (p ∘ f))
id ┴ └──┘ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ └─┘ ┴ ┴└─────┘ ┴ ┴ ┴
src └──┘ └─┘ └────┘ ┴ └─┘ └─────┘ ┴
typ ┴ └──┘ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ └─┘ ┴ ┴└─────┘ ┴ ┴ ┴
2985 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2986 | (b::l) := by by_cases p (f b); simp [h, erasep_map l]
id └┘ ┴ ┴ ┴ ┴ └────────┘ ┴
src └┘ └───────┘ ┴ ┴ ┴ └────┘ └┘ ┴ └─
typ └┘ └───────┘┴┴ ┴┴┴┴ └────┘┴└┘└────────┘┴┴└─
doc └───────┘ ┴ ┴ ┴ └────┘ └┘ ┴ └─
txt └───────┘ ┴ ┴ ┴ └────┘ └┘ ┴ └─
par └───────┘ ┴ ┴ ┴ └────┘ └┘ ┴ └─
pid ┴ ┴ ┴ ┴ ┴┴ └┘ ┴ ┴└
st └─────────────────────────────────────────
2987
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2988 @[simp] theorem extractp_eq_find_erasep :
doc └──┘
2989 ∀ l : list α, extractp p l = (find p l, erasep p l)
id ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ ┴└──┘ ┴ ┴ └────┘ ┴ ┴
src └──┘ └──────┘ ┴ ┴└──┘ └────┘
typ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ ┴└──┘ ┴ ┴ └────┘ ┴ ┴
doc └──┘
2990 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
2991 | (a::l) := by by_cases pa : p a; simp [extractp, pa, extractp_eq_find_erasep l]
id └┘ ┴ ┴ └──────┘ └┘ └─────────────────────┘ ┴
src └┘ └───────┘ └─┘ ┴ └────┘└──────┘└┘ └┘ ┴ └─
typ └┘ └───────┘ └─┘┴┴┴ └────┘└──────┘└┘└┘└┘└─────────────────────┘┴┴└─
doc └───────┘ └─┘ ┴ └────┘ └┘ └┘ ┴ └─
txt └───────┘ └─┘ ┴ └────┘ └┘ └┘ ┴ └─
par └───────┘ └─┘ ┴ └────┘ └┘ └┘ ┴ └─
pid ┴ └─┘ ┴ ┴┴ └┘ └┘ ┴ ┴└
st └──────────────────────────────────────────────────────────────────
2992
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
2993 end erasep
2994
2995 /- erase -/
2996 section erase
2997 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
2998
2999 @[simp] theorem erase_nil (a : α) : [].erase a = [] := rfl
id ┴ └┘└───┘ ┴ ┴ └┘ └─┘
src └┘└───┘ ┴ └┘ └─┘
typ ┴ └┘└───┘ ┴ ┴ └┘ └─┘
doc └──┘
3000
3001 theorem erase_cons (a b : α) (l : list α) : (b :: l).erase a = if b = a then l else b :: l.erase a := rfl
id ┴ └──┘ ┴ ┴ └┘ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴└────┘ ┴ └─┘
src └──┘ └┘ └───┘ ┴ ┴ └┘ └────┘ └─┘
typ ┴ └──┘ ┴ ┴ └┘ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴└────┘ ┴ └─┘
3002
3003 @[simp] theorem erase_cons_head (a : α) (l : list α) : (a :: l).erase a = l :=
id ┴ └──┘ ┴ ┴ └┘ ┴ └───┘ ┴ ┴ ┴
src └──┘ └┘ └───┘ ┴
typ ┴ └──┘ ┴ ┴ └┘ ┴ └───┘ ┴ ┴ ┴
doc └──┘
3004 by simp only [erase_cons, if_pos rfl]
id └────────┘ └────┘ └─┘
src └─────────┘└────────┘└┘└────┘┴└─┘└─
typ └─────────┘└────────┘└┘└────┘┴└─┘└─
doc └─────────┘ └┘ ┴ └─
txt └─────────┘ └┘ ┴ └─
par └─────────┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ ┴ ┴└
st └───────────────────────────────────
3005
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3006 @[simp] theorem erase_cons_tail {a b : α} (l : list α) (h : b ≠ a) : (b::l).erase a = b :: l.erase a :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴ └┘ ┴└────┘ ┴
src └──┘ ┴ └┘ └───┘ ┴ └┘ └────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴ └┘ ┴└────┘ ┴
doc └──┘
3007 by simp only [erase_cons, if_neg h]; split; refl
id └────────┘ └────┘ ┴
src └─────────┘└────────┘└┘└────┘┴ ┴ └───┘ └────
typ └─────────┘└────────┘└┘└────┘┴┴┴ └───┘ └────
doc └─────────┘ └┘ ┴ ┴ └───┘ └────
txt └─────────┘ └┘ ┴ ┴ └───┘ └────
par └─────────┘ └┘ ┴ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ ┴ ┴ └
st └──────────────────────────────────────────────
3008
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3009 theorem erase_eq_erasep (a : α) (l : list α) : l.erase a = l.erasep (eq a) :=
id ┴ └──┘ ┴ ┴└────┘ ┴ ┴ ┴└─────┘ └┘ ┴
src └──┘ └────┘ ┴ └─────┘ └┘
typ ┴ └──┘ ┴ ┴└────┘ ┴ ┴ ┴└─────┘ └┘ ┴
3010 by { induction l with b l, {refl},
id ┴
src └────────┘ └───────┘ └──┘
typ └────────┘┴└───────┘ └──┘
doc └────────┘ └───────┘ └──┘
txt └────────┘ └───────┘ └──┘
par └────────┘ └───────┘ └──┘
pid ┴ ┴└──────┘
st └─────────────────────┘└─────┘└┘└
3011 by_cases a = b; [simp [h], simp [h, ne.symm h, *]] }
id ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
src └───────┘ ┴┴┴ ┴└────┘ ┴ └────┘ └┘└─────┘┴ └──┘
typ └───────┘┴┴┴┴┴ ┴└────┘┴┴ └────┘┴└┘└─────┘┴┴└──┘
doc └───────┘ ┴ ┴ └────┘ ┴ └────┘ └┘ ┴ └──┘
txt └───────┘ ┴ ┴ └────┘ ┴ └────┘ └┘ ┴ └──┘
par └───────┘ ┴ ┴ └────┘ ┴ └────┘ └┘ ┴ └──┘
pid ┴ ┴ ┴ ┴┴ ┴ ┴┴ └┘ ┴ └──┘
st ───────────────────────────────────────────────────┘└─┘
3012
3013 @[simp] theorem erase_of_not_mem {a : α} {l : list α} (h : a ∉ l) : l.erase a = l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴
doc └──┘
3014 by rw [erase_eq_erasep, erasep_of_forall_not]; rintro b h' rfl; exact h h'
id └─────────────┘ └──────────────────┘ ┴ └┘
src └──┘└─────────────┘└┘└──────────────────┘┴ └─────────────┘ └────┘ ┴ └
typ └──┘└─────────────┘└┘└──────────────────┘┴ └─────────────┘ └────┘┴┴└┘└
doc └──┘ └┘ ┴ └─────────────┘ └────┘ ┴ └
txt └──┘ └┘ ┴ └─────────────┘ └────┘ ┴ └
par └──┘ └┘ ┴ └─────────────┘ └────┘ ┴ └
pid └┘ └┘ ┴ └───────┘ ┴ ┴ └
st └──────────────────┘└────────────────────┘┴└─────────────────────────────
3015
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3016 theorem exists_erase_eq {a : α} {l : list α} (h : a ∈ l) :
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴
3017 ∃ l₁ l₂, a ∉ l₁ ∧ l = l₁ ++ a :: l₂ ∧ l.erase a = l₁ ++ l₂ :=
id ┴ └┘ └┘┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴└────┘ ┴ ┴ └┘ └┘ └┘
src ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ └────┘ ┴ └┘
typ ┴ └┘ └┘┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴└────┘ ┴ ┴ └┘ └┘ └┘
3018 by rcases exists_of_erasep h rfl with ⟨_, l₁, l₂, h₁, rfl, h₂, h₃⟩;
id └──────────────┘ ┴ └─┘
src └─────┘└──────────────┘┴ ┴└─┘└────────────────────────────────┘
typ └─────┘└──────────────┘┴┴┴└─┘└────────────────────────────────┘
doc └─────┘ ┴ ┴ └────────────────────────────────┘
txt └─────┘ ┴ ┴ └────────────────────────────────┘
par └─────┘ ┴ ┴ └────────────────────────────────┘
pid ┴ ┴ ┴ └────────────────────────────────┘
st └─────────────────────────────────────────────────────────────────
3019 rw erase_eq_erasep; exact ⟨l₁, l₂, λ h, h₁ _ h rfl, h₂, h₃⟩
id └─────────────┘ └┘ └┘ └┘ └─┘ └┘ └┘
src └─┘└─────────────┘ └────┘ └┘ └┘ └──┘ └─┘ ┴└─┘└┘ └┘ └─
typ └─┘└─────────────┘ └────┘ └┘└┘└┘└┘ └──┘└┘└─┘ ┴└─┘└┘└┘└┘└┘└─
doc └─┘ └────┘ └┘ └┘ └──┘ └─┘ ┴ └┘ └┘ └─
txt └─┘ └────┘ └┘ └┘ └──┘ └─┘ ┴ └┘ └┘ └─
par └─┘ └────┘ └┘ └┘ └──┘ └─┘ ┴ └┘ └┘ └─
pid ┴ ┴ └┘ └┘ └──┘ └─┘ ┴ └┘ └┘ ┴└
st ─────┘└─────────────┘└─────────────────────────────────────────
3020
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3021 @[simp] theorem length_erase_of_mem {a : α} {l : list α} (h : a ∈ l) : length (l.erase a) = pred (length l) :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴└────┘ ┴ ┴ └──┘ └────┘ ┴
src └──┘ ┴ └────┘ └────┘ ┴ └──┘ └────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └────┘ ┴└────┘ ┴ ┴ └──┘ └────┘ ┴
doc └──┘
3022 by rw erase_eq_erasep; exact length_erasep_of_mem h rfl
id └─────────────┘ └──────────────────┘ ┴ └─┘
src └─┘└─────────────┘ └────┘└──────────────────┘┴ ┴└─┘└
typ └─┘└─────────────┘ └────┘└──────────────────┘┴┴┴└─┘└
doc └─┘ └────┘ ┴ ┴ └
txt └─┘ └────┘ ┴ ┴ └
par └─┘ └────┘ ┴ ┴ └
pid ┴ ┴ ┴ ┴ └
st └─────────────────────────────────────────────────────
3023
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3024 theorem erase_append_left {a : α} {l₁ : list α} (l₂) (h : a ∈ l₁) :
id ┴ └──┘ ┴ ┴ ┴ └┘
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ └┘
3025 (l₁++l₂).erase a = l₁.erase a ++ l₂ :=
id └┘└┘└┘ └───┘ ┴ ┴ └┘└────┘ ┴ └┘ └┘
src └┘ └───┘ ┴ └────┘ └┘
typ └┘└┘└┘ └───┘ ┴ ┴ └┘└────┘ ┴ └┘ └┘
3026 by simp [erase_eq_erasep]; exact erasep_append_left (by refl) l₂ h
id └─────────────┘ └────────────────┘ └┘ ┴
src └────┘└─────────────┘┴ └────┘└────────────────┘┴ ┴└──┘└┘ ┴ └
typ └────┘└─────────────┘┴ └────┘└────────────────┘┴ ┴└──┘└┘└┘┴┴└
doc └────┘ ┴ └────┘ ┴ ┴└──┘└┘ ┴ └
txt └────┘ ┴ └────┘ ┴ ┴└──┘└┘ ┴ └
par └────┘ ┴ └────┘ ┴ ┴└──┘└┘ ┴ └
pid ┴┴ ┴ ┴ ┴ └─────┘ ┴ └
st └───────────────────────────────────────────────────┘└───┘└──────
3027
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3028 theorem erase_append_right {a : α} {l₁ : list α} (l₂) (h : a ∉ l₁) :
id ┴ └──┘ ┴ ┴ ┴ └┘
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ └┘
3029 (l₁++l₂).erase a = l₁ ++ l₂.erase a :=
id └┘└┘└┘ └───┘ ┴ ┴ └┘ └┘ └┘└────┘ ┴
src └┘ └───┘ ┴ └┘ └────┘
typ └┘└┘└┘ └───┘ ┴ ┴ └┘ └┘ └┘└────┘ ┴
3030 by rw [erase_eq_erasep, erase_eq_erasep, erasep_append_right];
id └─────────────┘ └─────────────┘ └─────────────────┘
src └──┘└─────────────┘└┘└─────────────┘└┘└─────────────────┘┴
typ └──┘└─────────────┘└┘└─────────────┘└┘└─────────────────┘┴
doc └──┘ └┘ └┘ ┴
txt └──┘ └┘ └┘ ┴
par └──┘ └┘ └┘ ┴
pid └┘ └┘ └┘ ┴
st └──────────────────┘└───────────────┘└───────────────────┘┴└─
3031 rintro b h' rfl; exact h h'
id ┴ └┘
src └─────────────┘ └────┘ ┴ └
typ └─────────────┘ └────┘┴┴└┘└
doc └─────────────┘ └────┘ ┴ └
txt └─────────────┘ └────┘ ┴ └
par └─────────────┘ └────┘ ┴ └
pid └───────┘ ┴ ┴ └
st ───────────────────────────────
3032
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3033 theorem erase_sublist (a : α) (l : list α) : l.erase a <+ l :=
id ┴ └──┘ ┴ ┴└────┘ ┴ └┘ ┴
src └──┘ └────┘ └┘
typ ┴ └──┘ ┴ ┴└────┘ ┴ └┘ ┴
3034 by rw erase_eq_erasep; apply erasep_sublist
id └─────────────┘ └────────────┘
src └─┘└─────────────┘ └────┘└────────────┘└
typ └─┘└─────────────┘ └────┘└────────────┘└
doc └─┘ └────┘ └
txt └─┘ └────┘ └
par └─┘ └────┘ └
pid ┴ ┴ └
st └─────────────────────────────────────────
3035
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3036 theorem erase_subset (a : α) (l : list α) : l.erase a ⊆ l :=
id ┴ └──┘ ┴ ┴└────┘ ┴ ┴ ┴
src └──┘ └────┘ ┴
typ ┴ └──┘ ┴ ┴└────┘ ┴ ┴ ┴
3037 subset_of_sublist (erase_sublist a l)
id └───────────────┘ └───────────┘ ┴ ┴
src └───────────────┘ └───────────┘
typ └───────────────┘ └───────────┘ ┴ ┴
3038
3039 theorem erase_sublist_erase (a : α) {l₁ l₂ : list α} (h : l₁ <+ l₂) : l₁.erase a <+ l₂.erase a :=
id ┴ └──┘ ┴ └┘ └┘ └┘ └┘└────┘ ┴ └┘ └┘└────┘ ┴
src └──┘ └┘ └────┘ └┘ └────┘
typ ┴ └──┘ ┴ └┘ └┘ └┘ └┘└────┘ ┴ └┘ └┘└────┘ ┴
3040 by simp [erase_eq_erasep]; exact erasep_sublist_erasep h
id └─────────────┘ └───────────────────┘ ┴
src └────┘└─────────────┘┴ └────┘└───────────────────┘┴ └
typ └────┘└─────────────┘┴ └────┘└───────────────────┘┴┴└
doc └────┘ ┴ └────┘ ┴ └
txt └────┘ ┴ └────┘ ┴ └
par └────┘ ┴ └────┘ ┴ └
pid ┴┴ ┴ ┴ ┴ └
st └──────────────────────────────────────────────────────
3041
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3042 theorem mem_of_mem_erase {a b : α} {l : list α} : a ∈ l.erase b → a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴
3043 @erase_subset _ _ _ _ _
id └──────────┘
src └──────────┘
typ └──────────┘
3044
3045 @[simp] theorem mem_erase_of_ne {a b : α} {l : list α} (ab : a ≠ b) : a ∈ l.erase b ↔ a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ └────┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘
3046 by rw erase_eq_erasep; exact mem_erasep_of_neg ab.symm
id └─────────────┘ └───────────────┘ └─────┘
src └─┘└─────────────┘ └────┘└───────────────┘┴└─────┘└
typ └─┘└─────────────┘ └────┘└───────────────┘┴└─────┘└
doc └─┘ └────┘ ┴ └
txt └─┘ └────┘ ┴ └
par └─┘ └────┘ ┴ └
pid ┴ ┴ ┴ └
st └────────────────────────────────────────────────────
3047
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3048 theorem erase_comm (a b : α) (l : list α) : (l.erase a).erase b = (l.erase b).erase a :=
id ┴ └──┘ ┴ ┴└────┘ ┴ └───┘ ┴ ┴ ┴└────┘ ┴ └───┘ ┴
src └──┘ └────┘ └───┘ ┴ └────┘ └───┘
typ ┴ └──┘ ┴ ┴└────┘ ┴ └───┘ ┴ ┴ ┴└────┘ ┴ └───┘ ┴
3049 if ab : a = b then by rw ab else
id └┘ ┴ ┴ ┴ └┘
src └┘ ┴ └─┘ ┴
typ └┘ ┴ ┴ ┴ └─┘└┘┴
doc └─┘ ┴
txt └─┘ ┴
par └─┘ ┴
pid ┴ ┴
st └─────┘
3050 if ha : a ∈ l then
id └┘ ┴ ┴ ┴
src └┘ ┴
typ └┘ ┴ ┴ ┴
3051 if hb : b ∈ l then match l, l.erase a, exists_erase_eq ha, hb with
id └┘ ┴ ┴ ┴ ┴ ┴└────┘ ┴ └─────────────┘ └┘ └┘
src └┘ ┴ └────┘ └─────────────┘
typ └┘ ┴ ┴ ┴ ┴ ┴└────┘ ┴ └─────────────┘ └┘ └┘
3052 | ._, ._, ⟨l₁, l₂, ha', rfl, rfl⟩, hb :=
id └┘ └─┘
src └─┘
typ └┘ └─┘
3053 if h₁ : b ∈ l₁ then
id └┘ ┴ ┴
src └┘ ┴
typ └┘ ┴ ┴
3054 by rw [erase_append_left _ h₁, erase_append_left _ h₁,
id └───────────────┘ └┘ └───────────────┘ └┘
src └──┘└───────────────┘└─┘ └┘└───────────────┘└─┘ └─
typ └──┘└───────────────┘└─┘└┘└┘└───────────────┘└─┘└┘└─
doc └──┘ └─┘ └┘ └─┘ └─
txt └──┘ └─┘ └┘ └─┘ └─
par └──┘ └─┘ └┘ └─┘ └─
pid └┘ └─┘ └┘ └─┘ └─
st └─────────────────────────┘└──────────────────────┘└─
3055 erase_append_right _ (mt mem_of_mem_erase ha'), erase_cons_head]
id └────────────────┘ └┘ └──────────────┘ └─┘ └─────────────┘
src ──────────┘└────────────────┘└─┘ └┘┴└──────────────┘┴ └─┘└─────────────┘└─
typ ──────────┘└────────────────┘└─┘ └┘┴└──────────────┘┴└─┘└─┘└─────────────┘└─
doc ──────────┘ └─┘ ┴ ┴ └─┘ └─
txt ──────────┘ └─┘ ┴ ┴ └─┘ └─
par ──────────┘ └─┘ ┴ ┴ └─┘ └─
pid ──────────┘ └─┘ ┴ ┴ └─┘ ┴└
st ────────────────────────────────────────────────────────┘└───────────────┘┴└
3056 else
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘
3057 by rw [erase_append_right _ h₁, erase_append_right _ h₁, erase_append_right _ ha',
id └────────────────┘ └┘ └────────────────┘ └┘ └────────────────┘ └─┘
src └──┘└────────────────┘└─┘ └┘└────────────────┘└─┘ └┘└────────────────┘└─┘ └─
typ └──┘└────────────────┘└─┘└┘└┘└────────────────┘└─┘└┘└┘└────────────────┘└─┘└─┘└─
doc └──┘ └─┘ └┘ └─┘ └┘ └─┘ └─
txt └──┘ └─┘ └┘ └─┘ └┘ └─┘ └─
par └──┘ └─┘ └┘ └─┘ └┘ └─┘ └─
pid └┘ └─┘ └┘ └─┘ └┘ └─┘ └─
st └──────────────────────────┘└───────────────────────┘└────────────────────────┘└─
3058 erase_cons_tail _ ab, erase_cons_head]
id └─────────────┘ └┘ └─────────────┘
src ──────────┘└─────────────┘└─┘ └┘└─────────────┘└┘
typ ──────────┘└─────────────┘└─┘└┘└┘└─────────────┘└┘
doc ──────────┘ └─┘ └┘ └┘
txt ──────────┘ └─┘ └┘ └┘
par ──────────┘ └─┘ └┘ └┘
pid ──────────┘ └─┘ └┘ ┴┴
st ──────────────────────────────┘└───────────────┘┴┴
3059 end
3060 else by simp only [erase_of_not_mem hb, erase_of_not_mem (mt mem_of_mem_erase hb)]
id └──────────────┘ └┘ └──────────────┘ └┘ └──────────────┘ └┘
src └─────────┘└──────────────┘┴ └┘└──────────────┘┴ └┘┴└──────────────┘┴ └─┘
typ └─────────┘└──────────────┘┴└┘└┘└──────────────┘┴ └┘┴└──────────────┘┴└┘└─┘
doc └─────────┘ ┴ └┘ ┴ ┴ ┴ └─┘
txt └─────────┘ ┴ └┘ ┴ ┴ ┴ └─┘
par └─────────┘ ┴ └┘ ┴ ┴ ┴ └─┘
pid ┴└──┘└┘ ┴ └┘ ┴ ┴ ┴ └┘┴
st └──────────────────────────────────────────────────────────────────────────┘
3061 else by simp only [erase_of_not_mem ha, erase_of_not_mem (mt mem_of_mem_erase ha)]
id └──────────────┘ └┘ └──────────────┘ └┘ └──────────────┘ └┘
src └─────────┘└──────────────┘┴ └┘└──────────────┘┴ └┘┴└──────────────┘┴ └──
typ └─────────┘└──────────────┘┴└┘└┘└──────────────┘┴ └┘┴└──────────────┘┴└┘└──
doc └─────────┘ ┴ └┘ ┴ ┴ ┴ └──
txt └─────────┘ ┴ └┘ ┴ ┴ ┴ └──
par └─────────┘ ┴ └┘ ┴ ┴ ┴ └──
pid ┴└──┘└┘ ┴ └┘ ┴ ┴ ┴ └┘└
st └───────────────────────────────────────────────────────────────────────────
3062
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3063 theorem map_erase [decidable_eq β] {f : α → β} (finj : injective f) {a : α}
id └──────────┘ ┴ ┴ ┴ └───────┘ ┴ ┴
src └──────────┘ └───────┘
typ └──────────┘ ┴ ┴ ┴ └───────┘ ┴ ┴
3064 (l : list α) : map f (l.erase a) = (map f l).erase (f a) :=
id └──┘ ┴ └─┘ ┴ ┴└────┘ ┴ ┴ └─┘ ┴ ┴ └───┘ ┴ ┴
src └──┘ └─┘ └────┘ ┴ └─┘ └───┘
typ └──┘ ┴ └─┘ ┴ ┴└────┘ ┴ ┴ └─┘ ┴ ┴ └───┘ ┴ ┴
3065 by rw [erase_eq_erasep, erase_eq_erasep, erasep_map]; congr;
id └─────────────┘ └─────────────┘ └────────┘
src └──┘└─────────────┘└┘└─────────────┘└┘└────────┘┴ └───┘
typ └──┘└─────────────┘└┘└─────────────┘└┘└────────┘┴ └───┘
doc └──┘ └┘ └┘ ┴
txt └──┘ └┘ └┘ ┴ └───┘
par └──┘ └┘ └┘ ┴ └───┘
pid └┘ └┘ └┘ ┴
st └──────────────────┘└───────────────┘└──────────┘┴└────────
3066 ext b; simp [finj.eq_iff]
src └───┘ └────┘ └─
typ └───┘ └────┘└─────────┘└─
doc └───┘ └────┘ └─
txt └───┘ └────┘ └─
par └───┘ └────┘ └─
pid └┘ ┴┴ ┴└
st ─────────────────────────────
3067
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3068 theorem map_foldl_erase [decidable_eq β] {f : α → β} (finj : injective f) {l₁ l₂ : list α} :
id └──────────┘ ┴ ┴ ┴ └───────┘ ┴ └──┘ ┴
src └──────────┘ └───────┘ └──┘
typ └──────────┘ ┴ ┴ ┴ └───────┘ ┴ └──┘ ┴
3069 map f (foldl list.erase l₁ l₂) = foldl (λ l a, l.erase (f a)) (map f l₁) l₂ :=
id └─┘ ┴ └───┘ └────────┘ └┘ └┘ ┴ └───┘ ┴ ┴ ┴└────┘ ┴ ┴ └─┘ ┴ └┘ └┘
src └─┘ └───┘ └────────┘ ┴ └───┘ └────┘ └─┘
typ └─┘ ┴ └───┘ └────────┘ └┘ └┘ ┴ └───┘ ┴ ┴ ┴└────┘ ┴ ┴ └─┘ ┴ └┘ └┘
3070 by induction l₂ generalizing l₁; [refl,
id └┘ ┴
src └────────┘ └──────────────┘ ┴└──┘
typ └────────┘└┘└──────────────┘ ┴└──┘
doc └────────┘ └──────────────┘ └──┘
txt └────────┘ └──────────────┘ └──┘
par └────────┘ └──────────────┘ └──┘
pid ┴ ┴└─────────────┘
st └─────────────────────────────────────
3071 simp only [foldl_cons, map_erase finj, *]]
id └────────┘ └───────┘ └──┘
src └─────────┘└────────┘└┘└───────┘┴ └──┘
typ └─────────┘└────────┘└┘└───────┘┴└──┘└──┘
doc └─────────┘ └┘ ┴ └──┘
txt └─────────┘ └┘ ┴ └──┘
par └─────────┘ └┘ ┴ └──┘
pid ┴└──┘└┘ └┘ ┴ └──┘
st ─────────────────────────────────────────┘
3072
3073 @[simp] theorem count_erase_self (a : α) : ∀ (s : list α), count a (list.erase s a) = pred (count a s)
id ┴ ┴ └──┘ ┴ └───┘ ┴ └────────┘ ┴ ┴ ┴ └──┘ └───┘ ┴ ┴
src └──┘ └───┘ └────────┘ ┴ └──┘ └───┘
typ ┴ ┴ └──┘ ┴ └───┘ ┴ └────────┘ ┴ ┴ ┴ └──┘ └───┘ ┴ ┴
doc └──┘ └───┘ └───┘
3074 | [] := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
3075 | (h :: t) :=
id └┘
src └┘
typ └┘
3076 begin
st └─────
3077 rw erase_cons,
id └────────┘
src └─┘└────────┘
typ └─┘└────────┘
doc └─┘
txt └─┘
par └─┘
pid ┴
st ──────────────┘└─
3078 by_cases p : h = a,
id ┴ ┴ ┴
src └───────┘ └─┘ ┴┴┴
typ └───────┘ └─┘┴┴┴┴┴
doc └───────┘ └─┘ ┴ ┴
txt └───────┘ └─┘ ┴ ┴
par └───────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ───────────────────┘└─
3079 { rw [if_pos p, count_cons', if_pos p.symm], simp },
id └────┘ ┴ └─────────┘ └────┘ └────┘
src └──┘└────┘┴ └┘└─────────┘└┘└────┘┴└────┘┴ └───┘
typ └──┘└────┘┴┴└┘└─────────┘└┘└────┘┴└────┘┴ └───┘
doc └──┘ ┴ └┘ └┘ ┴ ┴ └───┘
txt └──┘ ┴ └┘ └┘ ┴ ┴ └───┘
par └──┘ ┴ └┘ └┘ ┴ ┴ └───┘
pid └┘ ┴ └┘ └┘ ┴ ┴ ┴
st ───┘└──────────┘└───────────┘└─────────────┘└──────┘└┘└
3080 { rw [if_neg p, count_cons', count_cons', if_neg (λ x : a = h, p x.symm), count_erase_self],
id └────┘ ┴ └─────────┘ └─────────┘ └────┘ ┴ ┴ ┴ ┴ └───┘ └──────────────┘
src └──┘└────┘┴ └┘└─────────┘└┘└─────────┘└┘└────┘┴ └───┘ ┴ ┴ └┘ ┴ └───┘└─┘ ┴
typ └──┘└────┘┴┴└┘└─────────┘└┘└─────────┘└┘└────┘┴ └───┘┴┴┴┴┴└┘┴┴ └───┘└─┘└──────────────┘┴
doc └──┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ ┴ └┘ ┴ └─┘ ┴
txt └──┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ ┴ └┘ ┴ └─┘ ┴
par └──┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ ┴ └┘ ┴ └─┘ ┴
pid └┘ ┴ └┘ └┘ └┘ ┴ └───┘ ┴ ┴ └┘ ┴ └─┘ ┴
st ───────────────┘└───────────┘└───────────┘└──────────────────────────────┘└────────────────┘└──
3081 simp, }
src └──┘
typ └──┘
doc └──┘
txt └──┘
par └──┘
st ───────┘└───
3082 end
st ──┘
3083
3084 @[simp] theorem count_erase_of_ne {a b : α} (ab : a ≠ b) : ∀ (s : list α), count a (list.erase s b) = count a s
id ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ └────────┘ ┴ ┴ ┴ └───┘ ┴ ┴
src ┴ └──┘ └───┘ └────────┘ ┴ └───┘
typ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ └────────┘ ┴ ┴ ┴ └───┘ ┴ ┴
doc └──┘ └───┘ └───┘
3085 | [] := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
3086 | (x :: xs) :=
id └┘
src └┘
typ └┘
3087 begin
st └─────
3088 rw erase_cons,
id └────────┘
src └─┘└────────┘
typ └─┘└────────┘
doc └─┘
txt └─┘
par └─┘
pid ┴
st ──────────────┘└─
3089 split_ifs with h,
src └──────────────┘
typ └──────────────┘
doc └──────────────┘
txt └──────────────┘
par └──────────────┘
pid ┴└────┘
st ─────────────────┘└─
3090 { rw [count_cons', h, if_neg ab], simp },
id └─────────┘ ┴ └────┘ └┘
src └──┘└─────────┘└┘ └┘└────┘┴ ┴ └───┘
typ └──┘└─────────┘└┘┴└┘└────┘┴└┘┴ └───┘
doc └──┘ └┘ └┘ ┴ ┴ └───┘
txt └──┘ └┘ └┘ ┴ ┴ └───┘
par └──┘ └┘ └┘ ┴ ┴ └───┘
pid └┘ └┘ └┘ ┴ ┴ ┴
st ───┘└─────────────┘└─┘└─────────┘└──────┘└┘└
3091 { rw [count_cons', count_cons', count_erase_of_ne] }
id └─────────┘ └─────────┘ └───────────────┘
src └──┘└─────────┘└┘└─────────┘└┘ └┘
typ └──┘└─────────┘└┘└─────────┘└┘└───────────────┘└┘
doc └──┘ └┘ └┘ └┘
txt └──┘ └┘ └┘ └┘
par └──┘ └┘ └┘ └┘
pid └┘ └┘ └┘ ┴┴
st ──────────────────┘└───────────┘└─────────────────┘┴┴└─
3092 end
st ──┘
3093
3094 end erase
3095
3096 /- diff -/
3097 section diff
3098 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
3099
3100 @[simp] theorem diff_nil (l : list α) : l.diff [] = l := rfl
id └──┘ ┴ ┴└───┘ └┘ ┴ ┴ └─┘
src └──┘ └───┘ └┘ ┴ └─┘
typ └──┘ ┴ ┴└───┘ └┘ ┴ ┴ └─┘
doc └──┘
3101
3102 @[simp] theorem diff_cons (l₁ l₂ : list α) (a : α) : l₁.diff (a::l₂) = (l₁.erase a).diff l₂ :=
id └──┘ ┴ ┴ └┘└───┘ ┴└┘└┘ ┴ └┘└────┘ ┴ └──┘ └┘
src └──┘ └───┘ └┘ ┴ └────┘ └──┘
typ └──┘ ┴ ┴ └┘└───┘ ┴└┘└┘ ┴ └┘└────┘ ┴ └──┘ └┘
doc └──┘
3103 if h : a ∈ l₁ then by simp only [list.diff, if_pos h]
id └┘ ┴ ┴ └┘ └───────┘ └────┘ ┴
src └┘ ┴ └─────────┘└───────┘└┘└────┘┴ └┘
typ └┘ ┴ ┴ └┘ └─────────┘└───────┘└┘└────┘┴┴└┘
doc └─────────┘ └┘ ┴ └┘
txt └─────────┘ └┘ ┴ └┘
par └─────────┘ └┘ ┴ └┘
pid ┴└──┘└┘ └┘ ┴ ┴┴
st └───────────────────────────────┘
3104 else by simp only [list.diff, if_neg h, erase_of_not_mem h]
id └───────┘ └────┘ ┴ └──────────────┘ ┴
src └─────────┘└───────┘└┘└────┘┴ └┘└──────────────┘┴ └─
typ └─────────┘└───────┘└┘└────┘┴┴└┘└──────────────┘┴┴└─
doc └─────────┘ └┘ ┴ └┘ ┴ └─
txt └─────────┘ └┘ ┴ └┘ ┴ └─
par └─────────┘ └┘ ┴ └┘ ┴ └─
pid ┴└──┘└┘ └┘ ┴ └┘ ┴ ┴└
st └────────────────────────────────────────────────────
3105
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3106 @[simp] theorem nil_diff (l : list α) : [].diff l = [] :=
id └──┘ ┴ └┘└──┘ ┴ ┴ └┘
src └──┘ └┘└──┘ ┴ └┘
typ └──┘ ┴ └┘└──┘ ┴ ┴ └┘
doc └──┘
3107 by induction l; [refl, simp only [*, diff_cons, erase_of_not_mem (not_mem_nil _)]]
id ┴ ┴ └───────┘ └──────────────┘ └─────────┘
src └────────┘ ┴└──┘ └────────────┘└───────┘└┘└──────────────┘┴ └─────────┘└──┘
typ └────────┘┴ ┴└──┘ └────────────┘└───────┘└┘└──────────────┘┴ └─────────┘└──┘
doc └────────┘ └──┘ └────────────┘ └┘ ┴ └──┘
txt └────────┘ └──┘ └────────────┘ └┘ ┴ └──┘
par └────────┘ └──┘ └────────────┘ └┘ ┴ └──┘
pid ┴ ┴└──┘└───┘ └┘ ┴ └──┘
st └──────────────────────────────────────────────────────────────────────────────┘
3108
3109 theorem diff_eq_foldl : ∀ (l₁ l₂ : list α), l₁.diff l₂ = foldl list.erase l₁ l₂
id ┴ └──┘ ┴ └┘└───┘ └┘ ┴ └───┘ └────────┘ └┘ └┘
src └──┘ └───┘ ┴ └───┘ └────────┘
typ ┴ └──┘ ┴ └┘└───┘ └┘ ┴ └───┘ └────────┘ └┘ └┘
3110 | l₁ [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3111 | l₁ (a::l₂) := (diff_cons l₁ l₂ a).trans (diff_eq_foldl _ _)
id └┘ ┴└┘└┘ └───────┘ └───┘ └───────────┘
src └┘ └───────┘ └───┘
typ └┘ ┴└┘└┘ └───────┘ └───┘ └───────────┘
3112
3113 @[simp] theorem diff_append (l₁ l₂ l₃ : list α) : l₁.diff (l₂ ++ l₃) = (l₁.diff l₂).diff l₃ :=
id └──┘ ┴ └┘└───┘ └┘ └┘ └┘ ┴ └┘└───┘ └┘ └──┘ └┘
src └──┘ └───┘ └┘ ┴ └───┘ └──┘
typ └──┘ ┴ └┘└───┘ └┘ └┘ └┘ ┴ └┘└───┘ └┘ └──┘ └┘
doc └──┘
3114 by simp only [diff_eq_foldl, foldl_append]
id └───────────┘ └──────────┘
src └─────────┘└───────────┘└┘└──────────┘└─
typ └─────────┘└───────────┘└┘└──────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────────────────
3115
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3116 @[simp] theorem map_diff [decidable_eq β] {f : α → β} (finj : injective f) {l₁ l₂ : list α} :
id └──────────┘ ┴ ┴ ┴ └───────┘ ┴ └──┘ ┴
src └──────────┘ └───────┘ └──┘
typ └──────────┘ ┴ ┴ ┴ └───────┘ ┴ └──┘ ┴
doc └──┘
3117 map f (l₁.diff l₂) = (map f l₁).diff (map f l₂) :=
id └─┘ ┴ └┘└───┘ └┘ ┴ └─┘ ┴ └┘ └──┘ └─┘ ┴ └┘
src └─┘ └───┘ ┴ └─┘ └──┘ └─┘
typ └─┘ ┴ └┘└───┘ └┘ ┴ └─┘ ┴ └┘ └──┘ └─┘ ┴ └┘
3118 by simp only [diff_eq_foldl, foldl_map, map_foldl_erase finj]
id └───────────┘ └───────┘ └─────────────┘ └──┘
src └─────────┘└───────────┘└┘└───────┘└┘└─────────────┘┴ └─
typ └─────────┘└───────────┘└┘└───────┘└┘└─────────────┘┴└──┘└─
doc └─────────┘ └┘ └┘ ┴ └─
txt └─────────┘ └┘ └┘ ┴ └─
par └─────────┘ └┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴└
st └───────────────────────────────────────────────────────────
3119
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3120 theorem diff_sublist : ∀ l₁ l₂ : list α, l₁.diff l₂ <+ l₁
id └┘ └──┘ ┴ └┘└───┘ └┘ └┘ └┘
src └──┘ └───┘ └┘
typ └┘ └──┘ ┴ └┘└───┘ └┘ └┘ └┘
3121 | l₁ [] := sublist.refl _
id └┘ └──────────┘
src └┘ └──────────┘
typ └┘ └──────────┘
3122 | l₁ (a::l₂) := calc l₁.diff (a :: l₂) = (l₁.erase a).diff l₂ : diff_cons _ _ _
id └┘ ┴└┘└┘ └───┘ └┘ └────┘ └──┘ └───────┘
src └┘ └───┘ └┘ └────┘ └──┘ └───────┘
typ └┘ ┴└┘└┘ └───┘ └┘ └────┘ └──┘ └───────┘
3123 ... <+ l₁.erase a : diff_sublist _ _
id └────┘ └──────────┘
src └────┘
typ └────┘ └──────────┘
3124 ... <+ l₁ : list.erase_sublist _ _
id └────────────────┘
src └────────────────┘
typ └────────────────┘
3125
3126 theorem diff_subset (l₁ l₂ : list α) : l₁.diff l₂ ⊆ l₁ :=
id └──┘ ┴ └┘└───┘ └┘ ┴ └┘
src └──┘ └───┘ ┴
typ └──┘ ┴ └┘└───┘ └┘ ┴ └┘
3127 subset_of_sublist $ diff_sublist _ _
id └───────────────┘ └──────────┘
src └───────────────┘ └──────────┘
typ └───────────────┘ └──────────┘
3128
3129 theorem mem_diff_of_mem {a : α} : ∀ {l₁ l₂ : list α}, a ∈ l₁ → a ∉ l₂ → a ∈ l₁.diff l₂
id ┴ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘└───┘ └┘
src └──┘ ┴ ┴ ┴ └───┘
typ ┴ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘└───┘ └┘
3130 | l₁ [] h₁ h₂ := h₁
id └┘ └┘
src └┘
typ └┘ └┘
3131 | l₁ (b::l₂) h₁ h₂ := by rw diff_cons; exact
id └┘ └───────┘
src └┘ └─┘└───────┘ └─────
typ └┘ └─┘└───────┘ └─────
doc └─┘ └─────
txt └─┘ └─────
par └─┘ └─────
pid ┴ └
st └────────────────────
3132 mem_diff_of_mem ((mem_erase_of_ne (ne_of_not_mem_cons h₂)).2 h₁) (not_mem_of_not_mem_cons h₂)
id └─────────────┘ └─────────────┘ └────────────────┘ └┘ └─────────────────────┘ └┘
src ─┘ ┴ └─────────────┘┴ └────────────────┘┴ └───┘ └┘ └─────────────────────┘┴ └─
typ ─┘└─────────────┘┴ └─────────────┘┴ └────────────────┘┴ └───┘└┘└┘ └─────────────────────┘┴└┘└─
doc ─┘ ┴ ┴ ┴ └───┘ └┘ ┴ └─
txt ─┘ ┴ ┴ ┴ └───┘ └┘ ┴ └─
par ─┘ ┴ ┴ ┴ └───┘ └┘ ┴ └─
pid ─┘ ┴ ┴ ┴ └───┘ └┘ ┴ ┴└
st ────────────────────────────────────────────────────────────────────────────────────────────────
3133
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3134 theorem diff_sublist_of_sublist : ∀ {l₁ l₂ l₃: list α}, l₁ <+ l₂ → l₁.diff l₃ <+ l₂.diff l₃
id ┴ └──┘ ┴ └┘ └┘ └┘ └┘└───┘ └┘ └┘ └┘└───┘ └┘
src └──┘ └┘ └───┘ └┘ └───┘
typ ┴ └──┘ ┴ └┘ └┘ └┘ └┘└───┘ └┘ └┘ └┘└───┘ └┘
3135 | l₁ l₂ [] h := h
id └┘ ┴
src └┘
typ └┘ ┴
3136 | l₁ l₂ (a::l₃) h := by simp only
id └┘
src └┘ └─────────
typ └┘ └─────────
doc └─────────
txt └─────────
par └─────────
pid ┴└──┘└
st └──────────
3137 [diff_cons, diff_sublist_of_sublist (erase_sublist_erase _ h)]
id └───────┘ └─────────────────────┘ └─────────────────┘ ┴
src ──┘└───────┘└┘ ┴ └─────────────────┘└─┘ └──
typ ──┘└───────┘└┘└─────────────────────┘┴ └─────────────────┘└─┘┴└──
doc ──┘ └┘ ┴ └─┘ └──
txt ──┘ └┘ ┴ └─┘ └──
par ──┘ └┘ ┴ └─┘ └──
pid ──┘ └┘ ┴ └─┘ └┘└
st ─────────────────────────────────────────────────────────────────
3138
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3139 theorem erase_diff_erase_sublist_of_sublist {a : α} : ∀ {l₁ l₂ : list α},
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
3140 l₁ <+ l₂ → (l₂.erase a).diff (l₁.erase a) <+ l₂.diff l₁
id └┘ └┘ └┘ └┘└────┘ ┴ └──┘ └┘└────┘ ┴ └┘ └┘└───┘ └┘
src └┘ └────┘ └──┘ └────┘ └┘ └───┘
typ └┘ └┘ └┘ └┘└────┘ ┴ └──┘ └┘└────┘ ┴ └┘ └┘└───┘ └┘
3141 | [] l₂ h := erase_sublist _ _
id └┘ └───────────┘
src └┘ └───────────┘
typ └┘ └───────────┘
3142 | (b::l₁) l₂ h := if heq : b = a then by simp only [heq, erase_cons_head, diff_cons]
id ┴└┘ └┘ ┴ ┴ └─┘ └─────────────┘ └───────┘
src └┘ └┘ ┴ └─────────┘└─┘└┘└─────────────┘└┘└───────┘└─
typ ┴└┘ └┘ ┴ ┴ └─────────┘└─┘└┘└─────────────┘└┘└───────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────
3143 else by simpa only [erase_cons_head, erase_cons_tail _ heq, diff_cons, erase_comm a b l₂]
id └─────────────┘ └─────────────┘ └─┘ └───────┘ └────────┘ ┴ ┴ └┘
src ─────────────────┘ └──────────┘└─────────────┘└┘└─────────────┘└─┘└─┘└┘└───────┘└┘└────────┘┴ ┴ ┴ └─
typ ─────────────────┘ └──────────┘└─────────────┘└┘└─────────────┘└─┘└─┘└┘└───────┘└┘└────────┘┴┴┴┴┴└┘└─
doc ─────────────────┘ └──────────┘ └┘ └─┘ └┘ └┘ ┴ ┴ ┴ └─
txt ─────────────────┘ └──────────┘ └┘ └─┘ └┘ └┘ ┴ ┴ ┴ └─
par ─────────────────┘ └──────────┘ └┘ └─┘ └┘ └┘ ┴ ┴ ┴ └─
pid ─────────────────┘ ┴└──┘└┘ └┘ └─┘ └┘ └┘ ┴ ┴ ┴ ┴└
st ─────────────────┘ └──────────────────────────────────────────────────────────────────────────────────
3144 using erase_diff_erase_sublist_of_sublist (erase_sublist_erase b h)
id └─────────────────────────────────┘ └─────────────────┘ ┴ ┴
src ───────────────────────┘ ┴ └─────────────────┘┴ ┴ └┘
typ ───────────────────────┘└─────────────────────────────────┘┴ └─────────────────┘┴┴┴┴└┘
doc ───────────────────────┘ ┴ ┴ ┴ └┘
txt ───────────────────────┘ ┴ ┴ ┴ └┘
par ───────────────────────┘ ┴ ┴ ┴ └┘
pid ─────────────────┘└────┘ ┴ ┴ ┴ ┴┴
st ─────────────────────────────────────────────────────────────────────────────────────┘
3145 using_well_founded wf_tacs
id └─────┘
src └─────┘
typ └─────┘
doc └─────┘
3146
3147 end diff
3148
3149 /- zip & unzip -/
3150
3151 @[simp] theorem zip_cons_cons (a : α) (b : β) (l₁ : list α) (l₂ : list β) :
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
doc └──┘
3152 zip (a :: l₁) (b :: l₂) = (a, b) :: zip l₁ l₂ := rfl
id └─┘ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴┴ ┴ └┘ └─┘ └┘ └┘ └─┘
src └─┘ └┘ └┘ ┴ ┴ └┘ └─┘ └─┘
typ └─┘ ┴ └┘ └┘ ┴ └┘ └┘ ┴ ┴┴ ┴ └┘ └─┘ └┘ └┘ └─┘
3153
3154 @[simp] theorem zip_nil_left (l : list α) : zip ([] : list β) l = [] := rfl
id └──┘ ┴ └─┘ └┘ └──┘ ┴ ┴ ┴ └┘ └─┘
src └──┘ └─┘ └┘ └──┘ ┴ └┘ └─┘
typ └──┘ ┴ └─┘ └┘ └──┘ ┴ ┴ ┴ └┘ └─┘
doc └──┘
3155
3156 @[simp] theorem zip_nil_right (l : list α) : zip l ([] : list β) = [] :=
id └──┘ ┴ └─┘ ┴ └┘ └──┘ ┴ ┴ └┘
src └──┘ └─┘ └┘ └──┘ ┴ └┘
typ └──┘ ┴ └─┘ ┴ └┘ └──┘ ┴ ┴ └┘
doc └──┘
3157 by cases l; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
3158
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3159 @[simp] theorem zip_swap : ∀ (l₁ : list α) (l₂ : list β),
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
doc └──┘
3160 (zip l₁ l₂).map prod.swap = zip l₂ l₁
id └─┘ └┘ └┘ └─┘ └───────┘ ┴ └─┘ └┘ └┘
src └─┘ └─┘ └───────┘ ┴ └─┘
typ └─┘ └┘ └┘ └─┘ └───────┘ ┴ └─┘ └┘ └┘
doc └───────┘
3161 | [] l₂ := (zip_nil_right _).symm
id └┘ └───────────┘ └──┘
src └┘ └───────────┘ └──┘
typ └┘ └───────────┘ └──┘
3162 | l₁ [] := by rw zip_nil_right; refl
id └┘ └───────────┘
src └┘ └─┘└───────────┘ └───┘
typ └┘ └─┘└───────────┘ └───┘
doc └─┘ └───┘
txt └─┘ └───┘
par └─┘ └───┘
pid ┴ ┴
st └──────────────────────┘
3163 | (a::l₁) (b::l₂) := by simp only [zip_cons_cons, map_cons, zip_swap l₁ l₂, prod.swap_prod_mk]; split; refl
id └┘ └┘ └───────────┘ └──────┘ └──────┘ └┘ └┘ └───────────────┘
src └┘ └┘ └─────────┘└───────────┘└┘└──────┘└┘ ┴ ┴ └┘└───────────────┘┴ └───┘ └────
typ └┘ └┘ └─────────┘└───────────┘└┘└──────┘└┘└──────┘┴└┘┴└┘└┘└───────────────┘┴ └───┘ └────
doc └─────────┘ └┘ └┘ ┴ ┴ └┘ ┴ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ ┴ └┘ ┴ └───┘ └────
par └─────────┘ └┘ └┘ ┴ ┴ └┘ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └┘ ┴ └
st └────────────────────────────────────────────────────────────────────────────────────
3164
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3165 @[simp] theorem length_zip : ∀ (l₁ : list α) (l₂ : list β),
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
doc └──┘
3166 length (zip l₁ l₂) = min (length l₁) (length l₂)
id └────┘ └─┘ └┘ └┘ ┴ └─┘ └────┘ └┘ └────┘ └┘
src └────┘ └─┘ ┴ └─┘ └────┘ └────┘
typ └────┘ └─┘ └┘ └┘ ┴ └─┘ └────┘ └┘ └────┘ └┘
3167 | [] l₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3168 | l₁ [] := by simp only [length, zip_nil_right, min_zero]
id └┘ └────┘ └───────────┘ └──────┘
src └┘ └─────────┘└────┘└┘└───────────┘└┘└──────┘└┘
typ └┘ └─────────┘└────┘└┘└───────────┘└┘└──────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st └───────────────────────────────────────────┘
3169 | (a::l₁) (b::l₂) := by by simp only [length, zip_cons_cons, length_zip l₁ l₂, min_add_add_right]
id └┘ └┘ └────┘ └───────────┘ └────────┘ └┘ └┘ └───────────────┘
src └┘ └┘ └─────────┘└────┘└┘└───────────┘└┘ ┴ ┴ └┘└───────────────┘└─
typ └┘ └┘ └─────────┘└────┘└┘└───────────┘└┘└────────┘┴└┘┴└┘└┘└───────────────┘└─
doc └─────────┘ └┘ └┘ ┴ ┴ └┘ └─
txt └─────────┘ └┘ └┘ ┴ ┴ └┘ └─
par └─────────┘ └┘ └┘ ┴ ┴ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └┘ ┴└
3170
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
3171 theorem zip_append : ∀ {l₁ l₂ r₁ r₂ : list α} (h : length l₁ = length l₂),
id ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
src └──┘ └────┘ ┴ └────┘
typ ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
3172 zip (l₁ ++ r₁) (l₂ ++ r₂) = zip l₁ l₂ ++ zip r₁ r₂
id └─┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └─┘ └┘ └┘ └┘ └─┘ └┘ └┘
src └─┘ └┘ └┘ ┴ └─┘ └┘ └─┘
typ └─┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴ └─┘ └┘ └┘ └┘ └─┘ └┘ └┘
3173 | [] l₂ r₁ r₂ h := by simp only [eq_nil_of_length_eq_zero h.symm]; refl
id └┘ └──────────────────────┘ └────┘
src └┘ └─────────┘└──────────────────────┘┴└────┘┴ └───┘
typ └┘ └─────────┘└──────────────────────┘┴└────┘┴ └───┘
doc └─────────┘ ┴ ┴ └───┘
txt └─────────┘ ┴ ┴ └───┘
par └─────────┘ ┴ ┴ └───┘
pid ┴└──┘└┘ ┴ ┴ ┴
st └─────────────────────────────────────────────────┘
3174 | l₁ [] r₁ r₂ h := by simp only [eq_nil_of_length_eq_zero h]; refl
id └┘ └──────────────────────┘ ┴
src └┘ └─────────┘└──────────────────────┘┴ ┴ └───┘
typ └┘ └─────────┘└──────────────────────┘┴┴┴ └───┘
doc └─────────┘ ┴ ┴ └───┘
txt └─────────┘ ┴ ┴ └───┘
par └─────────┘ ┴ ┴ └───┘
pid ┴└──┘└┘ ┴ ┴ ┴
st └────────────────────────────────────────────┘
3175 | (a::l₁) (b::l₂) r₁ r₂ h := by simp only [cons_append, zip_cons_cons, zip_append (succ_inj h)]; split; refl
id └┘ └┘ └─────────┘ └───────────┘ └────────┘ └──────┘ ┴
src └┘ └┘ └─────────┘└─────────┘└┘└───────────┘└┘ ┴ └──────┘┴ └┘ └───┘ └────
typ └┘ └┘ └─────────┘└─────────┘└┘└───────────┘└┘└────────┘┴ └──────┘┴┴└┘ └───┘ └────
doc └─────────┘ └┘ └┘ ┴ ┴ └┘ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ ┴ └┘ └───┘ └────
par └─────────┘ └┘ └┘ ┴ ┴ └┘ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └┘ └
st └─────────────────────────────────────────────────────────────────────────────
3176
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3177 theorem zip_map (f : α → γ) (g : β → δ) : ∀ (l₁ : list α) (l₂ : list β),
id ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──┘ ┴
3178 zip (l₁.map f) (l₂.map g) = (zip l₁ l₂).map (prod.map f g)
id └─┘ └┘└──┘ ┴ └┘└──┘ ┴ ┴ └─┘ └┘ └┘ └─┘ └──────┘ ┴ ┴
src └─┘ └──┘ └──┘ ┴ └─┘ └─┘ └──────┘
typ └─┘ └┘└──┘ ┴ └┘└──┘ ┴ ┴ └─┘ └┘ └┘ └─┘ └──────┘ ┴ ┴
3179 | [] l₂ := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3180 | l₁ [] := by simp only [map, zip_nil_right]
id └┘ └─┘ └───────────┘
src └┘ └─────────┘└─┘└┘└───────────┘└┘
typ └┘ └─────────┘└─┘└┘└───────────┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └──────────────────────────────┘
3181 | (a::l₁) (b::l₂) := by simp only [map, zip_cons_cons, zip_map l₁ l₂, prod.map]; split; refl
id └┘ └┘ └─┘ └───────────┘ └─────┘ └┘ └┘ └──────┘
src └┘ └┘ └─────────┘└─┘└┘└───────────┘└┘ ┴ ┴ └┘└──────┘┴ └───┘ └────
typ └┘ └┘ └─────────┘└─┘└┘└───────────┘└┘└─────┘┴└┘┴└┘└┘└──────┘┴ └───┘ └────
doc └─────────┘ └┘ └┘ ┴ ┴ └┘ ┴ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ ┴ └┘ ┴ └───┘ └────
par └─────────┘ └┘ └┘ ┴ ┴ └┘ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └┘ ┴ └
st └─────────────────────────────────────────────────────────────────────
3182
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3183 theorem zip_map_left (f : α → γ) (l₁ : list α) (l₂ : list β) :
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
3184 zip (l₁.map f) l₂ = (zip l₁ l₂).map (prod.map f id) :=
id └─┘ └┘└──┘ ┴ └┘ ┴ └─┘ └┘ └┘ └─┘ └──────┘ ┴ └┘
src └─┘ └──┘ ┴ └─┘ └─┘ └──────┘ └┘
typ └─┘ └┘└──┘ ┴ └┘ ┴ └─┘ └┘ └┘ └─┘ └──────┘ ┴ └┘
3185 by rw [← zip_map, map_id]
id └─────┘ └────┘
src └────┘└─────┘└┘└────┘└─
typ └────┘└─────┘└┘└────┘└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid └──┘ └┘ ┴└
st └────────────┘└──────┘┴└
3186
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3187 theorem zip_map_right (f : β → γ) (l₁ : list α) (l₂ : list β) :
id ┴ ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ ┴ └──┘ ┴ └──┘ ┴
3188 zip l₁ (l₂.map f) = (zip l₁ l₂).map (prod.map id f) :=
id └─┘ └┘ └┘└──┘ ┴ ┴ └─┘ └┘ └┘ └─┘ └──────┘ └┘ ┴
src └─┘ └──┘ ┴ └─┘ └─┘ └──────┘ └┘
typ └─┘ └┘ └┘└──┘ ┴ ┴ └─┘ └┘ └┘ └─┘ └──────┘ └┘ ┴
3189 by rw [← zip_map, map_id]
id └─────┘ └────┘
src └────┘└─────┘└┘└────┘└─
typ └────┘└─────┘└┘└────┘└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid └──┘ └┘ ┴└
st └────────────┘└──────┘┴└
3190
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3191 theorem zip_map' (f : α → β) (g : α → γ) : ∀ (l : list α),
id ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
3192 zip (l.map f) (l.map g) = l.map (λ a, (f a, g a))
id └─┘ ┴└──┘ ┴ ┴└──┘ ┴ ┴ ┴└──┘ ┴ ┴┴ ┴ ┴ ┴
src └─┘ └──┘ └──┘ ┴ └──┘ ┴
typ └─┘ ┴└──┘ ┴ ┴└──┘ ┴ ┴ ┴└──┘ ┴ ┴┴ ┴ ┴ ┴
3193 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3194 | (a::l) := by simp only [map, zip_cons_cons, zip_map' l]; split; refl
id └┘ └─┘ └───────────┘ └──────┘ ┴
src └┘ └─────────┘└─┘└┘└───────────┘└┘ ┴ ┴ └───┘ └────
typ └┘ └─────────┘└─┘└┘└───────────┘└┘└──────┘┴┴┴ └───┘ └────
doc └─────────┘ └┘ └┘ ┴ ┴ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ ┴ └───┘ └────
par └─────────┘ └┘ └┘ ┴ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └
st └────────────────────────────────────────────────────────
3195
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3196 theorem mem_zip {a b} : ∀ {l₁ : list α} {l₂ : list β},
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
3197 (a, b) ∈ zip l₁ l₂ → a ∈ l₁ ∧ b ∈ l₂
id ┴┴ ┴ ┴ └─┘ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src ┴ ┴ └─┘ ┴ ┴ ┴
typ ┴┴ ┴ ┴ └─┘ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘
3198 | (_::l₁) (_::l₂) (or.inl rfl) := ⟨or.inl rfl, or.inl rfl⟩
id └┘ └┘ └────┘ └─┘ └────┘ └─┘ └────┘ └─┘
src └┘ └┘ └────┘ └─┘ └────┘ └─┘ └────┘ └─┘
typ └┘ └┘ └────┘ └─┘ └────┘ └─┘ └────┘ └─┘
3199 | (a'::l₁) (b'::l₂) (or.inr h) := by split; simp only [mem_cons_iff, or_true, mem_zip h]
id └┘ └┘ └────┘ └──────────┘ └─────┘ └─────┘ ┴
src └┘ └┘ └────┘ └───┘ └─────────┘└──────────┘└┘└─────┘└┘ ┴ └─
typ └┘ └┘ └────┘ └───┘ └─────────┘└──────────┘└┘└─────┘└┘└─────┘┴┴└─
doc └───┘ └─────────┘ └┘ └┘ ┴ └─
txt └───┘ └─────────┘ └┘ └┘ ┴ └─
par └───┘ └─────────┘ └┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴└
st └────────────────────────────────────────────────────
3200
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3201 @[simp] theorem unzip_nil : unzip (@nil (α × β)) = ([], []) := rfl
id └───┘ └─┘ ┴ ┴ ┴ ┴ ┴└┘ └┘ └─┘
src └───┘ └─┘ ┴ ┴ ┴└┘ └┘ └─┘
typ └───┘ └─┘ ┴ ┴ ┴ ┴ ┴└┘ └┘ └─┘
doc └──┘
3202
3203 @[simp] theorem unzip_cons (a : α) (b : β) (l : list (α × β)) :
id ┴ ┴ └──┘ ┴ ┴ ┴
src └──┘ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴
doc └──┘
3204 unzip ((a, b) :: l) = (a :: (unzip l).1, b :: (unzip l).2) :=
id └───┘ ┴┴ ┴ └┘ ┴ ┴ ┴┴ └┘ └───┘ ┴ ┴ ┴ └┘ └───┘ ┴ ┴
src └───┘ ┴ └┘ ┴ ┴ └┘ └───┘ ┴ └┘ └───┘ ┴
typ └───┘ ┴┴ ┴ └┘ ┴ ┴ ┴┴ └┘ └───┘ ┴ ┴ ┴ └┘ └───┘ ┴ ┴
3205 by rw unzip; cases unzip l; refl
id └───┘ └───┘ ┴
src └─┘└───┘ └────┘└───┘┴ └────
typ └─┘└───┘ └────┘└───┘┴┴ └────
doc └─┘ └────┘ ┴ └────
txt └─┘ └────┘ ┴ └────
par └─┘ └────┘ ┴ └────
pid ┴ ┴ ┴ └
st └──────────────────────────────
3206
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3207 theorem unzip_eq_map : ∀ (l : list (α × β)), unzip l = (l.map prod.fst, l.map prod.snd)
id ┴ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴┴└──┘ └──────┘ ┴└──┘ └──────┘
src └──┘ ┴ └───┘ ┴ ┴ └──┘ └──────┘ └──┘ └──────┘
typ ┴ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴┴└──┘ └──────┘ ┴└──┘ └──────┘
3208 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3209 | ((a, b) :: l) := by simp only [unzip_cons, map_cons, unzip_eq_map l]
id ┴ └┘ └────────┘ └──────┘ └──────────┘ ┴
src ┴ └┘ └─────────┘└────────┘└┘└──────┘└┘ ┴ └─
typ ┴ └┘ └─────────┘└────────┘└┘└──────┘└┘└──────────┘┴┴└─
doc └─────────┘ └┘ └┘ ┴ └─
txt └─────────┘ └┘ └┘ ┴ └─
par └─────────┘ └┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴└
st └─────────────────────────────────────────────────
3210
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3211 theorem unzip_left (l : list (α × β)) : (unzip l).1 = l.map prod.fst :=
id └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴└──┘ └──────┘
src └──┘ ┴ └───┘ ┴ ┴ └──┘ └──────┘
typ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴└──┘ └──────┘
3212 by simp only [unzip_eq_map]
id └──────────┘
src └─────────┘└──────────┘└─
typ └─────────┘└──────────┘└─
doc └─────────┘ └─
txt └─────────┘ └─
par └─────────┘ └─
pid ┴└──┘└┘ ┴└
st └─────────────────────────
3213
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3214 theorem unzip_right (l : list (α × β)) : (unzip l).2 = l.map prod.snd :=
id └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴└──┘ └──────┘
src └──┘ ┴ └───┘ ┴ ┴ └──┘ └──────┘
typ └──┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴└──┘ └──────┘
3215 by simp only [unzip_eq_map]
id └──────────┘
src └─────────┘└──────────┘└─
typ └─────────┘└──────────┘└─
doc └─────────┘ └─
txt └─────────┘ └─
par └─────────┘ └─
pid ┴└──┘└┘ ┴└
st └─────────────────────────
3216
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3217 theorem unzip_swap (l : list (α × β)) : unzip (l.map prod.swap) = (unzip l).swap :=
id └──┘ ┴ ┴ ┴ └───┘ ┴└──┘ └───────┘ ┴ └───┘ ┴ └──┘
src └──┘ ┴ └───┘ └──┘ └───────┘ ┴ └───┘ └──┘
typ └──┘ ┴ ┴ ┴ └───┘ ┴└──┘ └───────┘ ┴ └───┘ ┴ └──┘
doc └───────┘ └──┘
3218 by simp only [unzip_eq_map, map_map]; split; refl
id └──────────┘ └─────┘
src └─────────┘└──────────┘└┘└─────┘┴ └───┘ └────
typ └─────────┘└──────────┘└┘└─────┘┴ └───┘ └────
doc └─────────┘ └┘ ┴ └───┘ └────
txt └─────────┘ └┘ ┴ └───┘ └────
par └─────────┘ └┘ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ ┴ └
st └───────────────────────────────────────────────
3219
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3220 theorem zip_unzip : ∀ (l : list (α × β)), zip (unzip l).1 (unzip l).2 = l
id ┴ └──┘ ┴ ┴ ┴ └─┘ └───┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └─┘ └───┘ ┴ └───┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └─┘ └───┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴
3221 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3222 | ((a, b) :: l) := by simp only [unzip_cons, zip_cons_cons, zip_unzip l]; split; refl
id ┴ └┘ └────────┘ └───────────┘ └───────┘ ┴
src ┴ └┘ └─────────┘└────────┘└┘└───────────┘└┘ ┴ ┴ └───┘ └────
typ ┴ └┘ └─────────┘└────────┘└┘└───────────┘└┘└───────┘┴┴┴ └───┘ └────
doc └─────────┘ └┘ └┘ ┴ ┴ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ ┴ └───┘ └────
par └─────────┘ └┘ └┘ ┴ ┴ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └
st └────────────────────────────────────────────────────────────────
3223
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3224 theorem unzip_zip_left : ∀ {l₁ : list α} {l₂ : list β}, length l₁ ≤ length l₂ →
id ┴ └──┘ ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
src └──┘ └──┘ └────┘ ┴ └────┘
typ ┴ └──┘ ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
3225 (unzip (zip l₁ l₂)).1 = l₁
id └───┘ └─┘ └┘ └┘ ┴ ┴ └┘
src └───┘ └─┘ ┴ ┴
typ └───┘ └─┘ └┘ └┘ ┴ ┴ └┘
3226 | [] l₂ h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3227 | l₁ [] h := by rw eq_nil_of_length_eq_zero (eq_zero_of_le_zero h); refl
id └┘ └──────────────────────┘ └────────────────┘ ┴
src └┘ └─┘└──────────────────────┘┴ └────────────────┘┴ ┴ └───┘
typ └┘ └─┘└──────────────────────┘┴ └────────────────┘┴┴┴ └───┘
doc └─┘ ┴ ┴ ┴ └───┘
txt └─┘ ┴ ┴ ┴ └───┘
par └─┘ ┴ ┴ ┴ └───┘
pid ┴ ┴ ┴ ┴ ┴
st └────────────────────────────────────────────────────────┘
3228 | (a::l₁) (b::l₂) h := by simp only [zip_cons_cons, unzip_cons, unzip_zip_left (le_of_succ_le_succ h)]; split; refl
id └┘ └┘ └───────────┘ └────────┘ └────────────┘ └────────────────┘ ┴
src └┘ └┘ └─────────┘└───────────┘└┘└────────┘└┘ ┴ └────────────────┘┴ └┘ └───┘ └────
typ └┘ └┘ └─────────┘└───────────┘└┘└────────┘└┘└────────────┘┴ └────────────────┘┴┴└┘ └───┘ └────
doc └─────────┘ └┘ └┘ ┴ ┴ └┘ └───┘ └────
txt └─────────┘ └┘ └┘ ┴ ┴ └┘ └───┘ └────
par └─────────┘ └┘ └┘ ┴ ┴ └┘ └───┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ ┴ └┘ └
st └──────────────────────────────────────────────────────────────────────────────────────────
3229
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3230 theorem unzip_zip_right {l₁ : list α} {l₂ : list β} (h : length l₂ ≤ length l₁) :
id └──┘ ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
src └──┘ └──┘ └────┘ ┴ └────┘
typ └──┘ ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
3231 (unzip (zip l₁ l₂)).2 = l₂ :=
id └───┘ └─┘ └┘ └┘ ┴ ┴ └┘
src └───┘ └─┘ ┴ ┴
typ └───┘ └─┘ └┘ └┘ ┴ ┴ └┘
3232 by rw [← zip_swap, unzip_swap]; exact unzip_zip_left h
id └──────┘ └────────┘ └────────────┘ ┴
src └────┘└──────┘└┘└────────┘┴ └────┘└────────────┘┴ └
typ └────┘└──────┘└┘└────────┘┴ └────┘└────────────┘┴┴└
doc └────┘ └┘ ┴ └────┘ ┴ └
txt └────┘ └┘ ┴ └────┘ ┴ └
par └────┘ └┘ ┴ └────┘ ┴ └
pid └──┘ └┘ ┴ ┴ ┴ └
st └─────────────┘└──────────┘┴└────────────────────────
3233
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3234 theorem unzip_zip {l₁ : list α} {l₂ : list β} (h : length l₁ = length l₂) :
id └──┘ ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
src └──┘ └──┘ └────┘ ┴ └────┘
typ └──┘ ┴ └──┘ ┴ └────┘ └┘ ┴ └────┘ └┘
3235 unzip (zip l₁ l₂) = (l₁, l₂) :=
id └───┘ └─┘ └┘ └┘ ┴ ┴└┘ └┘
src └───┘ └─┘ ┴ ┴
typ └───┘ └─┘ └┘ └┘ ┴ ┴└┘ └┘
3236 by rw [← @prod.mk.eta _ _ (unzip (zip l₁ l₂)),
id └─────────┘ └───┘ └─┘ └┘ └┘
src └────┘ └─────────┘└───┘ └───┘┴ └─┘┴ ┴ └───
typ └────┘ └─────────┘└───┘ └───┘┴ └─┘┴└┘┴└┘└───
doc └────┘ └───┘ ┴ ┴ ┴ └───
txt └────┘ └───┘ ┴ ┴ ┴ └───
par └────┘ └───┘ ┴ ┴ ┴ └───
pid └──┘ └───┘ ┴ ┴ ┴ └───
st └─────────────────────────────────────────┘└─
3237 unzip_zip_left (le_of_eq h), unzip_zip_right (ge_of_eq h)]
id └────────────┘ └──────┘ ┴ └─────────────┘ └──────┘ ┴
src ─┘└────────────┘┴ └──────┘┴ └─┘└─────────────┘┴ └──────┘┴ └──
typ ─┘└────────────┘┴ └──────┘┴┴└─┘└─────────────┘┴ └──────┘┴┴└──
doc ─┘ ┴ ┴ └─┘ ┴ ┴ └──
txt ─┘ ┴ ┴ └─┘ ┴ ┴ └──
par ─┘ ┴ ┴ └─┘ ┴ ┴ └──
pid ─┘ ┴ ┴ └─┘ ┴ ┴ └┘└
st ────────────────────────────┘└────────────────────────────┘┴└
3238
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3239 @[simp] theorem length_revzip (l : list α) : length (revzip l) = length l :=
id └──┘ ┴ └────┘ └────┘ ┴ ┴ └────┘ ┴
src └──┘ └────┘ └────┘ ┴ └────┘
typ └──┘ ┴ └────┘ └────┘ ┴ ┴ └────┘ ┴
doc └──┘
3240 by simp only [revzip, length_zip, length_reverse, min_self]
id └────┘ └────────┘ └────────────┘ └──────┘
src └─────────┘└────┘└┘└────────┘└┘└────────────┘└┘└──────┘└─
typ └─────────┘└────┘└┘└────────┘└┘└────────────┘└┘└──────┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────
3241
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3242 @[simp] theorem unzip_revzip (l : list α) : (revzip l).unzip = (l, l.reverse) :=
id └──┘ ┴ └────┘ ┴ └───┘ ┴ ┴┴ ┴└──────┘
src └──┘ └────┘ └───┘ ┴ ┴ └──────┘
typ └──┘ ┴ └────┘ ┴ └───┘ ┴ ┴┴ ┴└──────┘
doc └──┘
3243 unzip_zip (length_reverse l).symm
id └───────┘ └────────────┘ ┴ └──┘
src └───────┘ └────────────┘ └──┘
typ └───────┘ └────────────┘ ┴ └──┘
3244
3245 @[simp] theorem revzip_map_fst (l : list α) : (revzip l).map prod.fst = l :=
id └──┘ ┴ └────┘ ┴ └─┘ └──────┘ ┴ ┴
src └──┘ └────┘ └─┘ └──────┘ ┴
typ └──┘ ┴ └────┘ ┴ └─┘ └──────┘ ┴ ┴
doc └──┘
3246 by rw [← unzip_left, unzip_revzip]
id └────────┘ └──────────┘
src └────┘└────────┘└┘└──────────┘└─
typ └────┘└────────┘└┘└──────────┘└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid └──┘ └┘ ┴└
st └───────────────┘└────────────┘┴└
3247
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3248 @[simp] theorem revzip_map_snd (l : list α) : (revzip l).map prod.snd = l.reverse :=
id └──┘ ┴ └────┘ ┴ └─┘ └──────┘ ┴ ┴└──────┘
src └──┘ └────┘ └─┘ └──────┘ ┴ └──────┘
typ └──┘ ┴ └────┘ ┴ └─┘ └──────┘ ┴ ┴└──────┘
doc └──┘
3249 by rw [← unzip_right, unzip_revzip]
id └─────────┘ └──────────┘
src └────┘└─────────┘└┘└──────────┘└─
typ └────┘└─────────┘└┘└──────────┘└─
doc └────┘ └┘ └─
txt └────┘ └┘ └─
par └────┘ └┘ └─
pid └──┘ └┘ ┴└
st └────────────────┘└────────────┘┴└
3250
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3251 theorem reverse_revzip (l : list α) : reverse l.revzip = revzip l.reverse :=
id └──┘ ┴ └─────┘ ┴└─────┘ ┴ └────┘ ┴└──────┘
src └──┘ └─────┘ └─────┘ ┴ └────┘ └──────┘
typ └──┘ ┴ └─────┘ ┴└─────┘ ┴ └────┘ ┴└──────┘
3252 by rw [← zip_unzip.{u u} (revzip l).reverse, unzip_eq_map]; simp; simp [revzip]
id └───────┘ └────┘ ┴ └──────────┘ └────┘
src └────┘└───────┘└─────┘ └────┘┴ └─────────┘└──────────┘┴ └──┘ └────┘└────┘└─
typ └────┘└───────┘└─────┘ └────┘┴┴└─────────┘└──────────┘┴ └──┘ └────┘└────┘└─
doc └────┘ └─────┘ ┴ └─────────┘ ┴ └──┘ └────┘ └─
txt └────┘ └─────┘ ┴ └─────────┘ ┴ └──┘ └────┘ └─
par └────┘ └─────┘ ┴ └─────────┘ ┴ └──┘ └────┘ └─
pid └──┘ └─────┘ ┴ └─────────┘ ┴ ┴┴ ┴└
st └──────────────────────────────────────┘└─────────────┘┴└─────────────────────
3253
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3254 theorem revzip_swap (l : list α) : (revzip l).map prod.swap = revzip l.reverse :=
id └──┘ ┴ └────┘ ┴ └─┘ └───────┘ ┴ └────┘ ┴└──────┘
src └──┘ └────┘ └─┘ └───────┘ ┴ └────┘ └──────┘
typ └──┘ ┴ └────┘ ┴ └─┘ └───────┘ ┴ └────┘ ┴└──────┘
doc └───────┘
3255 by simp [revzip]
id └────┘
src └────┘└────┘└─
typ └────┘└────┘└─
doc └────┘ └─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └──────────────
3256
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
3257 /- enum -/
src ───────────
typ ───────────
doc ───────────
txt ───────────
par ───────────
pid ───────────
st ───────────
3258
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3259 theorem length_enum_from : ∀ n (l : list α), length (enum_from n l) = length l
id ┴ └──┘ ┴ └────┘ └───────┘ ┴ ┴ ┴ └────┘ ┴
src └──┘ └────┘ └───────┘ ┴ └────┘
typ ┴ └──┘ ┴ └────┘ └───────┘ ┴ ┴ ┴ └────┘ ┴
3260 | n [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3261 | n (a::l) := congr_arg nat.succ (length_enum_from _ _)
id └┘ └───────┘ └──────┘ └──────────────┘
src └┘ └───────┘ └──────┘
typ └┘ └───────┘ └──────┘ └──────────────┘
3262
3263 theorem length_enum : ∀ (l : list α), length (enum l) = length l := length_enum_from _
id └──┘ ┴ └────┘ └──┘ ┴ ┴ └────┘ ┴ └──────────────┘
src └──┘ └────┘ └──┘ ┴ └────┘ └──────────────┘
typ └──┘ ┴ └────┘ └──┘ ┴ ┴ └────┘ ┴ └──────────────┘
3264
3265 @[simp] theorem enum_from_nth : ∀ n (l : list α) m,
id ┴ └──┘ ┴ ┴
src └──┘
typ ┴ └──┘ ┴ ┴
doc └──┘
3266 nth (enum_from n l) m = (λ a, (n + m, a)) <$> nth l m
id └─┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
src └─┘ └───────┘ ┴ ┴ ┴ └─┘ └─┘
typ └─┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴ ┴ └─┘ └─┘ ┴ ┴
3267 | n [] m := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3268 | n (a :: l) 0 := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3269 | n (a :: l) (m+1) := (enum_from_nth (n+1) l m).trans $
id ┴ └┘ ┴ ┴┴ └───────────┘ ┴ └───┘
src └┘ ┴ ┴ └───┘
typ ┴ └┘ ┴ ┴┴ └───────────┘ ┴ └───┘
3270 by rw [add_right_comm]; refl
id └────────────┘
src └──┘└────────────┘┴ └────
typ └──┘└────────────┘┴ └────
doc └──┘ ┴ └────
txt └──┘ ┴ └────
par └──┘ ┴ └────
pid └┘ ┴ └
st └─────────────────┘┴└──────
3271
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3272 @[simp] theorem enum_nth : ∀ (l : list α) n,
id └──┘ ┴ ┴
src └──┘
typ └──┘ ┴ ┴
doc └──┘
3273 nth (enum l) n = (λ a, (n, a)) <$> nth l n :=
id └─┘ └──┘ ┴ ┴ ┴ ┴ ┴┴ ┴ └─┘ └─┘ ┴ ┴
src └─┘ └──┘ ┴ ┴ └─┘ └─┘
typ └─┘ └──┘ ┴ ┴ ┴ ┴ ┴┴ ┴ └─┘ └─┘ ┴ ┴
3274 by simp only [enum, enum_from_nth, zero_add]; intros; refl
id └──┘ └───────────┘ └──────┘
src └─────────┘└──┘└┘└───────────┘└┘└──────┘┴ └────┘ └────
typ └─────────┘└──┘└┘└───────────┘└┘└──────┘┴ └────┘ └────
doc └─────────┘ └┘ └┘ ┴ └────┘ └────
txt └─────────┘ └┘ └┘ ┴ └────┘ └────
par └─────────┘ └┘ └┘ ┴ └────┘ └────
pid ┴└──┘└┘ └┘ └┘ ┴ └
st └────────────────────────────────────────────────────────
3275
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3276 @[simp] theorem enum_from_map_snd : ∀ n (l : list α),
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
3277 map prod.snd (enum_from n l) = l
id └─┘ └──────┘ └───────┘ ┴ ┴ ┴ ┴
src └─┘ └──────┘ └───────┘ ┴
typ └─┘ └──────┘ └───────┘ ┴ ┴ ┴ ┴
3278 | n [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3279 | n (a :: l) := congr_arg (cons _) (enum_from_map_snd _ _)
id └┘ └───────┘ └──┘ └───────────────┘
src └┘ └───────┘ └──┘
typ └┘ └───────┘ └──┘ └───────────────┘
3280
3281 @[simp] theorem enum_map_snd : ∀ (l : list α),
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
3282 map prod.snd (enum l) = l := enum_from_map_snd _
id └─┘ └──────┘ └──┘ ┴ ┴ ┴ └───────────────┘
src └─┘ └──────┘ └──┘ ┴ └───────────────┘
typ └─┘ └──────┘ └──┘ ┴ ┴ ┴ └───────────────┘
3283
3284 theorem mem_enum_from {x : α} {i : ℕ} : Π {j : ℕ} (xs : list α), (i, x) ∈ xs.enum_from j → j ≤ i ∧ i < j + xs.length ∧ x ∈ xs
id ┴ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴ ┴ └┘└────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘└─────┘ ┴ ┴ ┴ └┘
src ┴ ┴ └──┘ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴
typ ┴ ┴ ┴ ┴ └──┘ ┴ ┴┴ ┴ ┴ └┘└────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘└─────┘ ┴ ┴ ┴ └┘
3285 | j [] := by simp [enum_from]
id └┘ └───────┘
src └┘ └────┘└───────┘└┘
typ └┘ └────┘└───────┘└┘
doc └────┘ └┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st └────────────────┘
3286 | j (y :: ys) := by { simp [enum_from,mem_enum_from ys],
id └┘ └───────┘ └───────────┘ └┘
src └┘ └────┘└───────┘┴ ┴ ┴
typ └┘ └────┘└───────┘┴└───────────┘┴└┘┴
doc └────┘ ┴ ┴ ┴
txt └────┘ ┴ ┴ ┴
par └────┘ ┴ ┴ ┴
pid ┴┴ ┴ ┴ ┴
st └──────────────────────────────────┘└─
3287 rintro (h|h),
src └──────────┘
typ └──────────┘
doc └──────────┘
txt └──────────┘
par └──────────┘
pid └────┘
st ─────────────────────────────────┘└─
3288 { refine ⟨le_of_eq h.1.symm,h.1 ▸ _,or.inl h.2⟩,
id └──────┘ ┴ └────┘ ┴
src └─────┘ └──────┘┴ └──────┘ └─┘┴└─┘└────┘┴ └─┘
typ └─────┘ └──────┘┴ └──────┘ └─┘┴└─┘└────┘┴┴└─┘
doc └─────┘ ┴ └──────┘ └─┘ └─┘ ┴ └─┘
txt └─────┘ ┴ └──────┘ └─┘ └─┘ ┴ └─┘
par └─────┘ ┴ └──────┘ └─┘ └─┘ ┴ └─┘
pid ┴ ┴ └──────┘ └─┘ └─┘ ┴ └─┘
st ───────────────────────┘└───────────────────────────────────────────┘└─
3289 apply lt_of_lt_of_le (nat.lt_add_of_pos_right zero_lt_one),
id └────────────┘ └─────────────────────┘ └─────────┘
src └────┘└────────────┘┴ └─────────────────────┘┴└─────────┘┴
typ └────┘└────────────┘┴ └─────────────────────┘┴└─────────┘┴
doc └────┘ ┴ ┴ ┴
txt └────┘ ┴ ┴ ┴
par └────┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ─────────────────────────────────────────────────────────────────────────────────┘└─
3290 apply nat.add_le_add_left, apply nat.le_add_right },
id └─────────────────┘ └──────────────┘
src └────┘└─────────────────┘ └────┘└──────────────┘┴
typ └────┘└─────────────────┘ └────┘└──────────────┘┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ────────────────────────────────────────────────┘└───────────────────────┘└┘└
3291 { replace h := mem_enum_from _ h,
id └───────────┘ ┴
src └───────────┘ └─┘
typ └───────────┘└───────────┘└─┘┴
doc └───────────┘ └─┘
txt └───────────┘ └─┘
par └───────────┘ └─┘
pid └┘┴└─┘ └─┘
st ─────────────────────────────────────────────────────┘└─
3292 simp at h, revert h, apply and_implies _ (and_implies id or.inr),
id └─────────┘ └┘ └────┘
src └───────┘ └──────┘ └────┘ └─┘ └─────────┘┴└┘┴└────┘┴
typ └───────┘ └──────┘ └────┘ └─┘ └─────────┘┴└┘┴└────┘┴
doc └───────┘ └──────┘ └────┘ └─┘ ┴ ┴ ┴
txt └───────┘ └──────┘ └────┘ └─┘ ┴ ┴ ┴
par └───────┘ └──────┘ └────┘ └─┘ ┴ ┴ ┴
pid ┴└──┘ └┘ ┴ └─┘ ┴ ┴ ┴
st ────────────────────────────────┘└────────┘└───────────────────────────────────────────┘└─
3293 intro h, transitivity j+1, apply nat.le_add_right, exact h } }
id ┴┴ └──────────────┘ ┴
src └─────┘ └───────────┘ ┴┴ └────┘└──────────────┘ └────┘ ┴
typ └─────┘ └───────────┘┴┴┴ └────┘└──────────────┘ └────┘┴┴
doc └─────┘ └───────────┘ ┴ └────┘ └────┘ ┴
txt └─────┘ └───────────┘ ┴ └────┘ └────┘ ┴
par └─────┘ └───────────┘ ┴ └────┘ └────┘ ┴
pid └┘ ┴ ┴ ┴ ┴ ┴
st ──────────────────────────────┘└────────────────┘└──────────────────────┘└────────┘└──┘
3294
3295 /- product -/
3296
3297 @[simp] theorem nil_product (l : list β) : product (@nil α) l = [] := rfl
id └──┘ ┴ └─────┘ └─┘ ┴ ┴ ┴ └┘ └─┘
src └──┘ └─────┘ └─┘ ┴ └┘ └─┘
typ └──┘ ┴ └─────┘ └─┘ ┴ ┴ ┴ └┘ └─┘
doc └──┘ └─────┘
3298
3299 @[simp] theorem product_cons (a : α) (l₁ : list α) (l₂ : list β)
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
doc └──┘
3300 : product (a::l₁) l₂ = map (λ b, (a, b)) l₂ ++ product l₁ l₂ := rfl
id └─────┘ ┴└┘└┘ └┘ ┴ └─┘ ┴ ┴┴ ┴ └┘ └┘ └─────┘ └┘ └┘ └─┘
src └─────┘ └┘ ┴ └─┘ ┴ └┘ └─────┘ └─┘
typ └─────┘ ┴└┘└┘ └┘ ┴ └─┘ ┴ ┴┴ ┴ └┘ └┘ └─────┘ └┘ └┘ └─┘
doc └─────┘ └─────┘
3301
3302 @[simp] theorem product_nil : ∀ (l : list α), product l (@nil β) = []
id ┴ └──┘ ┴ └─────┘ ┴ └─┘ ┴ ┴ └┘
src └──┘ └─────┘ └─┘ ┴ └┘
typ ┴ └──┘ ┴ └─────┘ ┴ └─┘ ┴ ┴ └┘
doc └──┘ └─────┘
3303 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3304 | (a::l) := by rw [product_cons, product_nil]; refl
id └┘ └──────────┘ └─────────┘
src └┘ └──┘└──────────┘└┘ ┴ └────
typ └┘ └──┘└──────────┘└┘└─────────┘┴ └────
doc └──┘ └┘ ┴ └────
txt └──┘ └┘ ┴ └────
par └──┘ └┘ ┴ └────
pid └┘ └┘ ┴ └
st └───────────────┘└───────────┘┴└──────
3305
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3306 @[simp] theorem mem_product {l₁ : list α} {l₂ : list β} {a : α} {b : β} :
id └──┘ ┴ └──┘ ┴ ┴ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴ ┴ ┴
doc └──┘
3307 (a, b) ∈ product l₁ l₂ ↔ a ∈ l₁ ∧ b ∈ l₂ :=
id ┴┴ ┴ ┴ └─────┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src ┴ ┴ └─────┘ ┴ ┴ ┴ ┴
typ ┴┴ ┴ ┴ └─────┘ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └─────┘
3308 by simp only [product, mem_bind, mem_map, prod.ext_iff, exists_prop,
id └─────┘ └──────┘ └─────┘ └──────────┘ └─────────┘
src └─────────┘└─────┘└┘└──────┘└┘└─────┘└┘└──────────┘└┘└─────────┘└─
typ └─────────┘└─────┘└┘└──────┘└┘└─────┘└┘└──────────┘└┘└─────────┘└─
doc └─────────┘└─────┘└┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └─
st └──────────────────────────────────────────────────────────────────
3309 and.left_comm, exists_and_distrib_left, exists_eq_left, exists_eq_right]
id └───────────┘ └─────────────────────┘ └────────────┘ └─────────────┘
src ─┘└───────────┘└┘└─────────────────────┘└┘└────────────┘└┘└─────────────┘└─
typ ─┘└───────────┘└┘└─────────────────────┘└┘└────────────┘└┘└─────────────┘└─
doc ─┘ └┘ └┘ └┘ └─
txt ─┘ └┘ └┘ └┘ └─
par ─┘ └┘ └┘ └┘ └─
pid ─┘ └┘ └┘ └┘ ┴└
st ───────────────────────────────────────────────────────────────────────────
3310
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3311 theorem length_product (l₁ : list α) (l₂ : list β) :
id └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ └──┘ ┴ └──┘ ┴
3312 length (product l₁ l₂) = length l₁ * length l₂ :=
id └────┘ └─────┘ └┘ └┘ ┴ └────┘ └┘ ┴ └────┘ └┘
src └────┘ └─────┘ ┴ └────┘ ┴ └────┘
typ └────┘ └─────┘ └┘ └┘ ┴ └────┘ └┘ ┴ └────┘ └┘
doc └─────┘
3313 by induction l₁ with x l₁ IH; [exact (zero_mul _).symm,
id └┘ ┴ └──────┘
src └────────┘ └───────────┘ ┴└────┘ └──────┘└──────┘
typ └────────┘└┘└───────────┘ ┴└────┘ └──────┘└──────┘
doc └────────┘ └───────────┘ └────┘ └──────┘
txt └────────┘ └───────────┘ └────┘ └──────┘
par └────────┘ └───────────┘ └────┘ └──────┘
pid ┴ ┴└──────────┘ ┴ └─────┘┴
st └─────────────────────────────────────────────────────
3314 simp only [length, product_cons, length_append, IH,
id └────┘ └──────────┘ └───────────┘ └┘
src └─────────┘└────┘└┘└──────────┘└┘└───────────┘└┘ └─
typ └─────────┘└────┘└┘└──────────┘└┘└───────────┘└┘└┘└─
doc └─────────┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └─
st ──────────────────────────────────────────────────────
3315 right_distrib, one_mul, length_map, add_comm]]
id └───────────┘ └─────┘ └────────┘ └──────┘
src ───┘└───────────┘└┘└─────┘└┘└────────┘└┘└──────┘┴
typ ───┘└───────────┘└┘└─────┘└┘└────────┘└┘└──────┘┴
doc ───┘ └┘ └┘ └┘ ┴
txt ───┘ └┘ └┘ └┘ ┴
par ───┘ └┘ └┘ └┘ ┴
pid ───┘ └┘ └┘ └┘ ┴
st ─────────────────────────────────────────────────┘
3316
3317
3318 /- sigma -/
3319 section
3320 variable {σ : α → Type*}
3321
3322 @[simp] theorem nil_sigma (l : Π a, list (σ a)) : (@nil α).sigma l = [] := rfl
id ┴ └──┘ ┴ ┴ └─┘ ┴ └───┘ ┴ ┴ └┘ └─┘
src └──┘ └─┘ └───┘ ┴ └┘ └─┘
typ ┴ └──┘ ┴ ┴ └─┘ ┴ └───┘ ┴ ┴ └┘ └─┘
doc └──┘ └───┘
3323
3324 @[simp] theorem sigma_cons (a : α) (l₁ : list α) (l₂ : Π a, list (σ a))
id ┴ └──┘ ┴ ┴ └──┘ ┴ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴
doc └──┘
3325 : (a::l₁).sigma l₂ = map (sigma.mk a) (l₂ a) ++ l₁.sigma l₂ := rfl
id ┴└┘└┘ └───┘ └┘ ┴ └─┘ └──────┘ ┴ └┘ ┴ └┘ └┘└────┘ └┘ └─┘
src └┘ └───┘ ┴ └─┘ └──────┘ └┘ └────┘ └─┘
typ ┴└┘└┘ └───┘ └┘ ┴ └─┘ └──────┘ ┴ └┘ ┴ └┘ └┘└────┘ └┘ └─┘
doc └───┘ └────┘
3326
3327 @[simp] theorem sigma_nil : ∀ (l : list α), l.sigma (λ a, @nil (σ a)) = []
id ┴ └──┘ ┴ ┴└────┘ ┴ └─┘ ┴ ┴ ┴ └┘
src └──┘ └────┘ └─┘ ┴ └┘
typ ┴ └──┘ ┴ ┴└────┘ ┴ └─┘ ┴ ┴ ┴ └┘
doc └──┘ └────┘
3328 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3329 | (a::l) := by rw [sigma_cons, sigma_nil]; refl
id └┘ └────────┘ └───────┘
src └┘ └──┘└────────┘└┘ ┴ └────
typ └┘ └──┘└────────┘└┘└───────┘┴ └────
doc └──┘ └┘ ┴ └────
txt └──┘ └┘ ┴ └────
par └──┘ └┘ ┴ └────
pid └┘ └┘ ┴ └
st └─────────────┘└─────────┘┴└──────
3330
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3331 @[simp] theorem mem_sigma {l₁ : list α} {l₂ : Π a, list (σ a)} {a : α} {b : σ a} :
id └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴
doc └──┘
3332 sigma.mk a b ∈ l₁.sigma l₂ ↔ a ∈ l₁ ∧ b ∈ l₂ a :=
id └──────┘ ┴ ┴ ┴ └┘└────┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴
src └──────┘ ┴ └────┘ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴ ┴ └┘└────┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴
doc └────┘
3333 by simp only [list.sigma, mem_bind, mem_map, exists_prop, exists_and_distrib_left,
id └────────┘ └──────┘ └─────┘ └─────────┘ └─────────────────────┘
src └─────────┘└────────┘└┘└──────┘└┘└─────┘└┘└─────────┘└┘└─────────────────────┘└─
typ └─────────┘└────────┘└┘└──────┘└┘└─────┘└┘└─────────┘└┘└─────────────────────┘└─
doc └─────────┘└────────┘└┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └─
st └────────────────────────────────────────────────────────────────────────────────
3334 and.left_comm, exists_eq_left, heq_iff_eq, exists_eq_right]
id └───────────┘ └────────────┘ └────────┘ └─────────────┘
src ─┘└───────────┘└┘└────────────┘└┘└────────┘└┘└─────────────┘└─
typ ─┘└───────────┘└┘└────────────┘└┘└────────┘└┘└─────────────┘└─
doc ─┘ └┘ └┘ └┘ └─
txt ─┘ └┘ └┘ └┘ └─
par ─┘ └┘ └┘ └┘ └─
pid ─┘ └┘ └┘ └┘ ┴└
st ──────────────────────────────────────────────────────────────
3335
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3336 theorem length_sigma (l₁ : list α) (l₂ : Π a, list (σ a)) :
id └──┘ ┴ ┴ └──┘ ┴ ┴
src └──┘ └──┘
typ └──┘ ┴ ┴ └──┘ ┴ ┴
3337 length (l₁.sigma l₂) = (l₁.map (λ a, length (l₂ a))).sum :=
id └────┘ └┘└────┘ └┘ ┴ └┘└──┘ ┴ └────┘ └┘ ┴ └─┘
src └────┘ └────┘ ┴ └──┘ └────┘ └─┘
typ └────┘ └┘└────┘ └┘ ┴ └┘└──┘ ┴ └────┘ └┘ ┴ └─┘
doc └────┘ └─┘
3338 by induction l₁ with x l₁ IH; [refl,
id └┘ ┴
src └────────┘ └───────────┘ ┴└──┘
typ └────────┘└┘└───────────┘ ┴└──┘
doc └────────┘ └───────────┘ └──┘
txt └────────┘ └───────────┘ └──┘
par └────────┘ └───────────┘ └──┘
pid ┴ ┴└──────────┘
st └──────────────────────────────────
3339 simp only [map, sigma_cons, length_append, length_map, IH, sum_cons]]
id └─┘ └────────┘ └───────────┘ └────────┘ └┘ └──────┘
src └─────────┘└─┘└┘└────────┘└┘└───────────┘└┘└────────┘└┘ └┘└──────┘┴
typ └─────────┘└─┘└┘└────────┘└┘└───────────┘└┘└────────┘└┘└┘└┘└──────┘┴
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ ┴
st ────────────────────────────────────────────────────────────────────┘
3340 end
3341
3342 /- of_fn -/
3343
3344 theorem length_of_fn_aux {n} (f : fin n → α) :
id └─┘ ┴ ┴
src └─┘
typ └─┘ ┴ ┴
3345 ∀ m h l, length (of_fn_aux f m h l) = length l + m
id ┴ ┴ ┴ └────┘ └───────┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴
src └────┘ └───────┘ ┴ └────┘ ┴
typ ┴ ┴ ┴ └────┘ └───────┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴
3346 | 0 h l := rfl
id └─┘
src └─┘
typ └─┘
3347 | (succ m) h l := (length_of_fn_aux m _ _).trans (succ_add _ _)
id └──┘ ┴ └──────────────┘ └───┘ └──────┘
src └──┘ └───┘ └──────┘
typ └──┘ ┴ └──────────────┘ └───┘ └──────┘
3348
3349 @[simp] theorem length_of_fn {n} (f : fin n → α) : length (of_fn f) = n :=
id └─┘ ┴ ┴ └────┘ └───┘ ┴ ┴ ┴
src └─┘ └────┘ └───┘ ┴
typ └─┘ ┴ ┴ └────┘ └───┘ ┴ ┴ ┴
doc └──┘
3350 (length_of_fn_aux f _ _ _).trans (zero_add _)
id └──────────────┘ ┴ └───┘ └──────┘
src └──────────────┘ └───┘ └──────┘
typ └──────────────┘ ┴ └───┘ └──────┘
3351
3352 theorem nth_of_fn_aux {n} (f : fin n → α) (i) :
id └─┘ ┴ ┴
src └─┘
typ └─┘ ┴ ┴
3353 ∀ m h l,
id ┴ ┴ ┴
typ ┴ ┴ ┴
3354 (∀ i, nth l i = of_fn_nth_val f (i + m)) →
id ┴ └─┘ ┴ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴
src └─┘ ┴ └───────────┘ ┴
typ ┴ └─┘ ┴ ┴ ┴ └───────────┘ ┴ ┴ ┴ ┴
3355 nth (of_fn_aux f m h l) i = of_fn_nth_val f i
id └─┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───────────┘ ┴ ┴
src └─┘ └───────┘ ┴ └───────────┘
typ └─┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───────────┘ ┴ ┴
3356 | 0 h l H := H i
id ┴ ┴
typ ┴ ┴
3357 | (succ m) h l H := nth_of_fn_aux m _ _ begin
id └──┘ ┴ └───────────┘
src └──┘
typ └──┘ ┴ └───────────┘
st └─────
3358 intro j, cases j with j,
id ┴
src └─────┘ └────┘ └─────┘
typ └─────┘ └────┘┴└─────┘
doc └─────┘ └────┘ └─────┘
txt └─────┘ └────┘ └─────┘
par └─────┘ └────┘ └─────┘
pid └┘ ┴ └─────┘
st ────────┘└──────────────┘└─
3359 { simp only [nth, of_fn_nth_val, zero_add, dif_pos (show m < n, from h)] },
id └─┘ └───────────┘ └──────┘ └─────┘ ┴ ┴ ┴ ┴
src └─────────┘└─┘└┘└───────────┘└┘└──────┘└┘└─────┘┴ ┴ ┴┴┴ └─────┘ └─┘
typ └─────────┘└─┘└┘└───────────┘└┘└──────┘└┘└─────┘┴ ┴┴┴┴┴┴└─────┘┴└─┘
doc └─────────┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └─────┘ └─┘
txt └─────────┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └─────┘ └─┘
par └─────────┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └─────┘ └─┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ ┴ ┴ ┴ └─────┘ └┘┴
st ───┘└─────────────────────────────────────────────────────────────────────┘└┘└
3360 { simp only [nth, H, succ_add] }
id └─┘ ┴ └──────┘
src └─────────┘└─┘└┘ └┘└──────┘└┘
typ └─────────┘└─┘└┘┴└┘└──────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st ────────────────────────────────┘└─
3361 end
st ──┘
3362
3363 @[simp] theorem nth_of_fn {n} (f : fin n → α) (i) :
id └─┘ ┴ ┴
src └─┘
typ └─┘ ┴ ┴
doc └──┘
3364 nth (of_fn f) i = of_fn_nth_val f i :=
id └─┘ └───┘ ┴ ┴ ┴ └───────────┘ ┴ ┴
src └─┘ └───┘ ┴ └───────────┘
typ └─┘ └───┘ ┴ ┴ ┴ └───────────┘ ┴ ┴
3365 nth_of_fn_aux f _ _ _ _ $ λ i,
id └───────────┘ ┴ ┴
src └───────────┘
typ └───────────┘ ┴ ┴
3366 by simp only [of_fn_nth_val, dif_neg (not_lt.2 (le_add_left n i))]; refl
id └───────────┘ └─────┘ └────┘ └─────────┘ ┴ ┴
src └─────────┘└───────────┘└┘└─────┘┴ └────┘└─┘ └─────────┘┴ ┴ └─┘ └────
typ └─────────┘└───────────┘└┘└─────┘┴ └────┘└─┘ └─────────┘┴┴┴┴└─┘ └────
doc └─────────┘ └┘ ┴ └─┘ ┴ ┴ └─┘ └────
txt └─────────┘ └┘ ┴ └─┘ ┴ ┴ └─┘ └────
par └─────────┘ └┘ ┴ └─┘ ┴ ┴ └─┘ └────
pid ┴└──┘└┘ └┘ ┴ └─┘ ┴ ┴ └─┘ └
st └──────────────────────────────────────────────────────────────────────
3367
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3368 @[simp] theorem nth_le_of_fn {n} (f : fin n → α) (i : fin n) :
id └─┘ ┴ ┴ └─┘ ┴
src └─┘ └─┘
typ └─┘ ┴ ┴ └─┘ ┴
doc └──┘
3369 nth_le (of_fn f) i.1 ((length_of_fn f).symm ▸ i.2) = f i :=
id └────┘ └───┘ ┴ ┴┴ └──────────┘ ┴ └──┘ ┴ ┴┴ ┴ ┴ ┴
src └────┘ └───┘ ┴ └──────────┘ └──┘ ┴ ┴ ┴
typ └────┘ └───┘ ┴ ┴┴ └──────────┘ ┴ └──┘ ┴ ┴┴ ┴ ┴ ┴
3370 option.some.inj $ by rw [← nth_le_nth];
id └─────────────┘ └────────┘
src └─────────────┘ └────┘└────────┘┴
typ └─────────────┘ └────┘└────────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid └──┘ ┴
st └───────────────┘┴└─
3371 simp only [list.nth_of_fn, of_fn_nth_val, fin.eta, dif_pos i.2]
id └────────────┘ └───────────┘ └─────┘ └─────┘ ┴
src └─────────┘└────────────┘└┘└───────────┘└┘└─────┘└┘└─────┘┴ └───
typ └─────────┘└────────────┘└┘└───────────┘└┘└─────┘└┘└─────┘┴┴└───
doc └─────────┘ └┘ └┘ └┘ ┴ └───
txt └─────────┘ └┘ └┘ └┘ ┴ └───
par └─────────┘ └┘ └┘ └┘ ┴ └───
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ └─┘└
st ──────────────────────────────────────────────────────────────────
3372
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3373 theorem array_eq_of_fn {n} (a : array n α) : a.to_list = of_fn a.read :=
id └───┘ ┴ ┴ ┴└──────┘ ┴ └───┘ ┴└───┘
src └───┘ └──────┘ ┴ └───┘ └───┘
typ └───┘ ┴ ┴ ┴└──────┘ ┴ └───┘ ┴└───┘
3374 suffices ∀ {m h l}, d_array.rev_iterate_aux a
id ┴ ┴ ┴ └─────────────────────┘ ┴
src └─────────────────────┘
typ ┴ ┴ ┴ └─────────────────────┘ ┴
3375 (λ i, cons) m h l = of_fn_aux (d_array.read a) m h l, from this,
id ┴ └──┘ ┴ ┴ ┴ ┴ └───────┘ └──────────┘ ┴ ┴ ┴ ┴ └──┘
src └──┘ ┴ └───────┘ └──────────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └───────┘ └──────────┘ ┴ ┴ ┴ ┴ └──┘
3376 begin
st └─────
3377 intros, induction m with m IH generalizing l, {refl},
id ┴
src └────┘ └────────┘ └───────────────────────┘ └──┘
typ └────┘ └────────┘┴└───────────────────────┘ └──┘
doc └────┘ └────────┘ └───────────────────────┘ └──┘
txt └────┘ └────────┘ └───────────────────────┘ └──┘
par └────┘ └────────┘ └───────────────────────┘ └──┘
pid ┴ ┴└───────┘└─────────────┘
st ───────┘└────────────────────────────────────┘└─────┘└┘└
3378 simp only [d_array.rev_iterate_aux, of_fn_aux, IH]
id └─────────────────────┘ └───────┘
src └─────────┘└─────────────────────┘└┘└───────┘└┘ └┘
typ └─────────┘└─────────────────────┘└┘└───────┘└┘└┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st ────────────────────────────────────────────────────┘
3379 end
st └─┘
3380
3381 theorem of_fn_zero (f : fin 0 → α) : of_fn f = [] := rfl
id └─┘ ┴ └───┘ ┴ ┴ └┘ └─┘
src └─┘ └───┘ ┴ └┘ └─┘
typ └─┘ ┴ └───┘ ┴ ┴ └┘ └─┘
3382
3383 theorem of_fn_succ {n} (f : fin (succ n) → α) :
id └─┘ └──┘ ┴ ┴
src └─┘ └──┘
typ └─┘ └──┘ ┴ ┴
3384 of_fn f = f 0 :: of_fn (λ i, f i.succ) :=
id └───┘ ┴ ┴ ┴ └┘ └───┘ ┴ ┴ ┴└───┘
src └───┘ ┴ └┘ └───┘ └───┘
typ └───┘ ┴ ┴ ┴ └┘ └───┘ ┴ ┴ ┴└───┘
3385 suffices ∀ {m h l}, of_fn_aux f (succ m) (succ_le_succ h) l =
id ┴ ┴ ┴ └───────┘ ┴ └──┘ ┴ └──────────┘ ┴ ┴ ┴
src └───────┘ └──┘ └──────────┘ ┴
typ ┴ ┴ ┴ └───────┘ ┴ └──┘ ┴ └──────────┘ ┴ ┴ ┴
3386 f 0 :: of_fn_aux (λ i, f i.succ) m h l, from this,
id ┴ └┘ └───────┘ ┴ ┴ ┴└───┘ ┴ ┴ ┴ └──┘
src └┘ └───────┘ └───┘
typ ┴ └┘ └───────┘ ┴ ┴ ┴└───┘ ┴ ┴ ┴ └──┘
3387 begin
st └─────
3388 intros, induction m with m IH generalizing l, {refl},
id ┴
src └────┘ └────────┘ └───────────────────────┘ └──┘
typ └────┘ └────────┘┴└───────────────────────┘ └──┘
doc └────┘ └────────┘ └───────────────────────┘ └──┘
txt └────┘ └────────┘ └───────────────────────┘ └──┘
par └────┘ └────────┘ └───────────────────────┘ └──┘
pid ┴ ┴└───────┘└─────────────┘
st ───────┘└────────────────────────────────────┘└─────┘└┘└
3389 rw [of_fn_aux, IH], refl
id └───────┘
src └──┘└───────┘└┘ ┴ └───┘
typ └──┘└───────┘└┘└┘┴ └───┘
doc └──┘ └┘ ┴ └───┘
txt └──┘ └┘ ┴ └───┘
par └──┘ └┘ ┴ └───┘
pid └┘ └┘ ┴ ┴
st ──────────────┘└──┘┴└─────┘
3390 end
st └─┘
3391
3392 theorem of_fn_nth_le : ∀ l : list α, of_fn (λ i, nth_le l i.1 i.2) = l
id ┴ └──┘ ┴ └───┘ ┴ └────┘ ┴ ┴┴ ┴┴ ┴ ┴
src └──┘ └───┘ └────┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ └───┘ ┴ └────┘ ┴ ┴┴ ┴┴ ┴ ┴
3393 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3394 | (a::l) := by rw of_fn_succ; congr; simp only [fin.succ_val]; exact of_fn_nth_le l
id └┘ └────────┘ └──────────┘ └──────────┘ ┴
src └┘ └─┘└────────┘ └───┘ └─────────┘└──────────┘┴ └────┘ ┴ └
typ └┘ └─┘└────────┘ └───┘ └─────────┘└──────────┘┴ └────┘└──────────┘┴┴└
doc └─┘ └─────────┘ ┴ └────┘ ┴ └
txt └─┘ └───┘ └─────────┘ ┴ └────┘ ┴ └
par └─┘ └───┘ └─────────┘ ┴ └────┘ ┴ └
pid ┴ ┴└──┘└┘ ┴ ┴ ┴ └
st └─────────────────────────────────────────────────────────────────────
3395
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
3396 /- disjoint -/
src ──────────────┘
typ ──────────────┘
doc ──────────────┘
txt ──────────────┘
par ──────────────┘
pid ──────────────┘
st ──────────────┘
3397 section disjoint
3398
3399 theorem disjoint.symm {l₁ l₂ : list α} (d : disjoint l₁ l₂) : disjoint l₂ l₁
id └──┘ ┴ └──────┘ └┘ └┘ └──────┘ └┘ └┘
src └──┘ └──────┘ └──────┘
typ └──┘ ┴ └──────┘ └┘ └┘ └──────┘ └┘ └┘
doc └──────┘ └──────┘
3400 | a i₂ i₁ := d i₁ i₂
id └┘ └┘ ┴
typ └┘ └┘ ┴
3401
3402 @[simp] theorem disjoint_comm {l₁ l₂ : list α} : disjoint l₁ l₂ ↔ disjoint l₂ l₁ :=
id └──┘ ┴ └──────┘ └┘ └┘ ┴ └──────┘ └┘ └┘
src └──┘ └──────┘ ┴ └──────┘
typ └──┘ ┴ └──────┘ └┘ └┘ ┴ └──────┘ └┘ └┘
doc └──┘ └──────┘ └──────┘
3403 ⟨disjoint.symm, disjoint.symm⟩
id └───────────┘ └───────────┘
src └───────────┘ └───────────┘
typ └───────────┘ └───────────┘
3404
3405 theorem disjoint_left {l₁ l₂ : list α} : disjoint l₁ l₂ ↔ ∀ {a}, a ∈ l₁ → a ∉ l₂ := iff.rfl
id └──┘ ┴ └──────┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘ └─────┘
src └──┘ └──────┘ ┴ ┴ ┴ └─────┘
typ └──┘ ┴ └──────┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘ └─────┘
doc └──────┘
3406
3407 theorem disjoint_right {l₁ l₂ : list α} : disjoint l₁ l₂ ↔ ∀ {a}, a ∈ l₂ → a ∉ l₁ :=
id └──┘ ┴ └──────┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘
src └──┘ └──────┘ ┴ ┴ ┴
typ └──┘ ┴ └──────┘ └┘ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘
doc └──────┘
3408 disjoint_comm
id └───────────┘
src └───────────┘
typ └───────────┘
3409
3410 theorem disjoint_iff_ne {l₁ l₂ : list α} : disjoint l₁ l₂ ↔ ∀ a ∈ l₁, ∀ b ∈ l₂, a ≠ b :=
id └──┘ ┴ └──────┘ └┘ └┘ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴
src └──┘ └──────┘ ┴ ┴
typ └──┘ ┴ └──────┘ └┘ └┘ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴
doc └──────┘
3411 by simp only [disjoint_left, imp_not_comm, forall_eq']
id └───────────┘ └──────────┘ └────────┘
src └─────────┘└───────────┘└┘└──────────┘└┘└────────┘└─
typ └─────────┘└───────────┘└┘└──────────┘└┘└────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────
3412
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3413 theorem disjoint_of_subset_left {l₁ l₂ l : list α} (ss : l₁ ⊆ l) (d : disjoint l l₂) : disjoint l₁ l₂
id └──┘ ┴ └┘ ┴ ┴ └──────┘ ┴ └┘ └──────┘ └┘ └┘
src └──┘ ┴ └──────┘ └──────┘
typ └──┘ ┴ └┘ ┴ ┴ └──────┘ ┴ └┘ └──────┘ └┘ └┘
doc └──────┘ └──────┘
3414 | x m₁ := d (ss m₁)
id └┘ ┴ └┘
typ └┘ ┴ └┘
3415
3416 theorem disjoint_of_subset_right {l₁ l₂ l : list α} (ss : l₂ ⊆ l) (d : disjoint l₁ l) : disjoint l₁ l₂
id └──┘ ┴ └┘ ┴ ┴ └──────┘ └┘ ┴ └──────┘ └┘ └┘
src └──┘ ┴ └──────┘ └──────┘
typ └──┘ ┴ └┘ ┴ ┴ └──────┘ └┘ ┴ └──────┘ └┘ └┘
doc └──────┘ └──────┘
3417 | x m m₁ := d m (ss m₁)
id ┴ └┘ ┴ └┘
typ ┴ └┘ ┴ └┘
3418
3419 theorem disjoint_of_disjoint_cons_left {a : α} {l₁ l₂} : disjoint (a::l₁) l₂ → disjoint l₁ l₂ :=
id ┴ └──────┘ ┴└┘└┘ └┘ └──────┘ └┘ └┘
src └──────┘ └┘ └──────┘
typ ┴ └──────┘ ┴└┘└┘ └┘ └──────┘ └┘ └┘
doc └──────┘ └──────┘
3420 disjoint_of_subset_left (list.subset_cons _ _)
id └─────────────────────┘ └──────────────┘
src └─────────────────────┘ └──────────────┘
typ └─────────────────────┘ └──────────────┘
3421
3422 theorem disjoint_of_disjoint_cons_right {a : α} {l₁ l₂} : disjoint l₁ (a::l₂) → disjoint l₁ l₂ :=
id ┴ └──────┘ └┘ ┴└┘└┘ └──────┘ └┘ └┘
src └──────┘ └┘ └──────┘
typ ┴ └──────┘ └┘ ┴└┘└┘ └──────┘ └┘ └┘
doc └──────┘ └──────┘
3423 disjoint_of_subset_right (list.subset_cons _ _)
id └──────────────────────┘ └──────────────┘
src └──────────────────────┘ └──────────────┘
typ └──────────────────────┘ └──────────────┘
3424
3425 @[simp] theorem disjoint_nil_left (l : list α) : disjoint [] l
id └──┘ ┴ └──────┘ └┘ ┴
src └──┘ └──────┘ └┘
typ └──┘ ┴ └──────┘ └┘ ┴
doc └──┘ └──────┘
3426 | a := (not_mem_nil a).elim
id ┴ └─────────┘ └──┘
src └─────────┘ └──┘
typ ┴ └─────────┘ └──┘
3427
3428 @[simp] theorem singleton_disjoint {l : list α} {a : α} : disjoint [a] l ↔ a ∉ l :=
id └──┘ ┴ ┴ └──────┘ ┴┴┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──────┘ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ └──────┘ ┴┴┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └──────┘
3429 by simp only [disjoint, mem_singleton, forall_eq]; refl
id └──────┘ └───────────┘ └───────┘
src └─────────┘└──────┘└┘└───────────┘└┘└───────┘┴ └────
typ └─────────┘└──────┘└┘└───────────┘└┘└───────┘┴ └────
doc └─────────┘└──────┘└┘ └┘ ┴ └────
txt └─────────┘ └┘ └┘ ┴ └────
par └─────────┘ └┘ └┘ ┴ └────
pid ┴└──┘└┘ └┘ └┘ ┴ └
st └─────────────────────────────────────────────────────
3430
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3431 @[simp] theorem disjoint_singleton {l : list α} {a : α} : disjoint l [a] ↔ a ∉ l :=
id └──┘ ┴ ┴ └──────┘ ┴ ┴┴┴ ┴ ┴ ┴ ┴
src └──┘ └──────┘ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ └──────┘ ┴ ┴┴┴ ┴ ┴ ┴ ┴
doc └──┘ └──────┘
3432 by rw disjoint_comm; simp only [singleton_disjoint]
id └───────────┘ └────────────────┘
src └─┘└───────────┘ └─────────┘└────────────────┘└─
typ └─┘└───────────┘ └─────────┘└────────────────┘└─
doc └─┘ └─────────┘ └─
txt └─┘ └─────────┘ └─
par └─┘ └─────────┘ └─
pid ┴ ┴└──┘└┘ ┴└
st └─────────────────────────────────────────────────
3433
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3434 @[simp] theorem disjoint_append_left {l₁ l₂ l : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
3435 disjoint (l₁++l₂) l ↔ disjoint l₁ l ∧ disjoint l₂ l :=
id └──────┘ └┘└┘└┘ ┴ ┴ └──────┘ └┘ ┴ ┴ └──────┘ └┘ ┴
src └──────┘ └┘ ┴ └──────┘ ┴ └──────┘
typ └──────┘ └┘└┘└┘ ┴ ┴ └──────┘ └┘ ┴ ┴ └──────┘ └┘ ┴
doc └──────┘ └──────┘ └──────┘
3436 by simp only [disjoint, mem_append, or_imp_distrib, forall_and_distrib]
id └──────┘ └────────┘ └────────────┘ └────────────────┘
src └─────────┘└──────┘└┘└────────┘└┘└────────────┘└┘└────────────────┘└─
typ └─────────┘└──────┘└┘└────────┘└┘└────────────┘└┘└────────────────┘└─
doc └─────────┘└──────┘└┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────────────
3437
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3438 @[simp] theorem disjoint_append_right {l₁ l₂ l : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
3439 disjoint l (l₁++l₂) ↔ disjoint l l₁ ∧ disjoint l l₂ :=
id └──────┘ ┴ └┘└┘└┘ ┴ └──────┘ ┴ └┘ ┴ └──────┘ ┴ └┘
src └──────┘ └┘ ┴ └──────┘ ┴ └──────┘
typ └──────┘ ┴ └┘└┘└┘ ┴ └──────┘ ┴ └┘ ┴ └──────┘ ┴ └┘
doc └──────┘ └──────┘ └──────┘
3440 disjoint_comm.trans $ by simp only [disjoint_comm, disjoint_append_left]
id └───────────┘└────┘ └───────────┘ └──────────────────┘
src └───────────┘└────┘ └─────────┘└───────────┘└┘└──────────────────┘└─
typ └───────────┘└────┘ └─────────┘└───────────┘└┘└──────────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────────────────────────
3441
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3442 @[simp] theorem disjoint_cons_left {a : α} {l₁ l₂ : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
3443 disjoint (a::l₁) l₂ ↔ a ∉ l₂ ∧ disjoint l₁ l₂ :=
id └──────┘ ┴└┘└┘ └┘ ┴ ┴ ┴ └┘ ┴ └──────┘ └┘ └┘
src └──────┘ └┘ ┴ ┴ ┴ └──────┘
typ └──────┘ ┴└┘└┘ └┘ ┴ ┴ ┴ └┘ ┴ └──────┘ └┘ └┘
doc └──────┘ └──────┘
3444 (@disjoint_append_left _ [a] l₁ l₂).trans $ by simp only [singleton_disjoint]
id └──────────────────┘ ┴┴┴ └┘ └┘ └───┘ └────────────────┘
src └──────────────────┘ ┴ ┴ └───┘ └─────────┘└────────────────┘└─
typ └──────────────────┘ ┴┴┴ └┘ └┘ └───┘ └─────────┘└────────────────┘└─
doc └─────────┘ └─
txt └─────────┘ └─
par └─────────┘ └─
pid ┴└──┘└┘ ┴└
st └───────────────────────────────
3445
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3446 @[simp] theorem disjoint_cons_right {a : α} {l₁ l₂ : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
3447 disjoint l₁ (a::l₂) ↔ a ∉ l₁ ∧ disjoint l₁ l₂ :=
id └──────┘ └┘ ┴└┘└┘ ┴ ┴ ┴ └┘ ┴ └──────┘ └┘ └┘
src └──────┘ └┘ ┴ ┴ ┴ └──────┘
typ └──────┘ └┘ ┴└┘└┘ ┴ ┴ ┴ └┘ ┴ └──────┘ └┘ └┘
doc └──────┘ └──────┘
3448 disjoint_comm.trans $ by simp only [disjoint_comm, disjoint_cons_left]
id └───────────┘└────┘ └───────────┘ └────────────────┘
src └───────────┘└────┘ └─────────┘└───────────┘└┘└────────────────┘└─
typ └───────────┘└────┘ └─────────┘└───────────┘└┘└────────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └──────────────────────────────────────────────
3449
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3450 theorem disjoint_of_disjoint_append_left_left {l₁ l₂ l : list α} (d : disjoint (l₁++l₂) l) : disjoint l₁ l :=
id └──┘ ┴ └──────┘ └┘└┘└┘ ┴ └──────┘ └┘ ┴
src └──┘ └──────┘ └┘ └──────┘
typ └──┘ ┴ └──────┘ └┘└┘└┘ ┴ └──────┘ └┘ ┴
doc └──────┘ └──────┘
3451 (disjoint_append_left.1 d).1
id └──────────────────┘┴ ┴ ┴
src └──────────────────┘┴ ┴
typ └──────────────────┘┴ ┴ ┴
3452
3453 theorem disjoint_of_disjoint_append_left_right {l₁ l₂ l : list α} (d : disjoint (l₁++l₂) l) : disjoint l₂ l :=
id └──┘ ┴ └──────┘ └┘└┘└┘ ┴ └──────┘ └┘ ┴
src └──┘ └──────┘ └┘ └──────┘
typ └──┘ ┴ └──────┘ └┘└┘└┘ ┴ └──────┘ └┘ ┴
doc └──────┘ └──────┘
3454 (disjoint_append_left.1 d).2
id └──────────────────┘┴ ┴ ┴
src └──────────────────┘┴ ┴
typ └──────────────────┘┴ ┴ ┴
3455
3456 theorem disjoint_of_disjoint_append_right_left {l₁ l₂ l : list α} (d : disjoint l (l₁++l₂)) : disjoint l l₁ :=
id └──┘ ┴ └──────┘ ┴ └┘└┘└┘ └──────┘ ┴ └┘
src └──┘ └──────┘ └┘ └──────┘
typ └──┘ ┴ └──────┘ ┴ └┘└┘└┘ └──────┘ ┴ └┘
doc └──────┘ └──────┘
3457 (disjoint_append_right.1 d).1
id └───────────────────┘┴ ┴ ┴
src └───────────────────┘┴ ┴
typ └───────────────────┘┴ ┴ ┴
3458
3459 theorem disjoint_of_disjoint_append_right_right {l₁ l₂ l : list α} (d : disjoint l (l₁++l₂)) : disjoint l l₂ :=
id └──┘ ┴ └──────┘ ┴ └┘└┘└┘ └──────┘ ┴ └┘
src └──┘ └──────┘ └┘ └──────┘
typ └──┘ ┴ └──────┘ ┴ └┘└┘└┘ └──────┘ ┴ └┘
doc └──────┘ └──────┘
3460 (disjoint_append_right.1 d).2
id └───────────────────┘┴ ┴ ┴
src └───────────────────┘┴ ┴
typ └───────────────────┘┴ ┴ ┴
3461
3462 end disjoint
3463
3464 /- union -/
3465 section union
3466 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
3467
3468 @[simp] theorem nil_union (l : list α) : [] ∪ l = l := rfl
id └──┘ ┴ └┘ ┴ ┴ ┴ ┴ └─┘
src └──┘ └┘ ┴ ┴ └─┘
typ └──┘ ┴ └┘ ┴ ┴ ┴ ┴ └─┘
doc └──┘
3469
3470 @[simp] theorem cons_union (l₁ l₂ : list α) (a : α) : a :: l₁ ∪ l₂ = insert a (l₁ ∪ l₂) := rfl
id └──┘ ┴ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └────┘ ┴ └┘ ┴ └┘ └─┘
src └──┘ └┘ ┴ ┴ └────┘ ┴ └─┘
typ └──┘ ┴ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └────┘ ┴ └┘ ┴ └┘ └─┘
doc └──┘
3471
3472 @[simp] theorem mem_union {l₁ l₂ : list α} {a : α} : a ∈ l₁ ∪ l₂ ↔ a ∈ l₁ ∨ a ∈ l₂ :=
id └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ ┴ ┴ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
3473 by induction l₁; simp only [nil_union, not_mem_nil, false_or, cons_union, mem_insert_iff, mem_cons_iff, or_assoc, *]
id └┘ └───────┘ └─────────┘ └──────┘ └────────┘ └────────────┘ └──────────┘ └──────┘
src └────────┘ └─────────┘└───────┘└┘└─────────┘└┘└──────┘└┘└────────┘└┘└────────────┘└┘└──────────┘└┘└──────┘└────
typ └────────┘└┘ └─────────┘└───────┘└┘└─────────┘└┘└──────┘└┘└────────┘└┘└────────────┘└┘└──────────┘└┘└──────┘└────
doc └────────┘ └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
txt └────────┘ └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
par └────────┘ └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └────
pid ┴ ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ └──┘└
st └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
3474
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3475 theorem mem_union_left {a : α} {l₁ : list α} (h : a ∈ l₁) (l₂ : list α) : a ∈ l₁ ∪ l₂ :=
id ┴ └──┘ ┴ ┴ ┴ └┘ └──┘ ┴ ┴ ┴ └┘ ┴ └┘
src └──┘ ┴ └──┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └┘ └──┘ ┴ ┴ ┴ └┘ ┴ └┘
3476 mem_union.2 (or.inl h)
id └───────┘┴ └────┘ ┴
src └───────┘┴ └────┘
typ └───────┘┴ └────┘ ┴
3477
3478 theorem mem_union_right {a : α} (l₁ : list α) {l₂ : list α} (h : a ∈ l₂) : a ∈ l₁ ∪ l₂ :=
id ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └┘
src └──┘ └──┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └┘
3479 mem_union.2 (or.inr h)
id └───────┘┴ └────┘ ┴
src └───────┘┴ └────┘
typ └───────┘┴ └────┘ ┴
3480
3481 theorem sublist_suffix_of_union : ∀ l₁ l₂ : list α, ∃ t, t <+ l₁ ∧ t ++ l₂ = l₁ ∪ l₂
id └┘ └──┘ ┴ ┴ ┴┴ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └┘
src └──┘ ┴ ┴ └┘ ┴ └┘ ┴ ┴
typ └┘ └──┘ ┴ ┴ ┴┴ ┴ └┘ └┘ ┴ ┴ └┘ └┘ ┴ └┘ ┴ └┘
3482 | [] l₂ := ⟨[], by refl, rfl⟩
id └┘ └┘ └─┘
src └┘ └┘ └──┘ └─┘
typ └┘ └┘ └──┘ └─┘
doc └──┘
txt └──┘
par └──┘
st └───┘
3483 | (a::l₁) l₂ := let ⟨t, s, e⟩ := sublist_suffix_of_union l₁ l₂ in
id ┴└┘└┘ └┘ └─┘ ┴ ┴ └─────────────────────┘
src └┘
typ ┴└┘└┘ └┘ └─┘ ┴ ┴ └─────────────────────┘
3484 if h : a ∈ l₁ ∪ l₂
id └┘ ┴ ┴
src └┘ ┴ ┴
typ └┘ ┴ ┴
3485 then ⟨t, sublist_cons_of_sublist _ s, by simp only [e, cons_union, insert_of_mem h]⟩
id └─────────────────────┘ ┴ └────────┘ └───────────┘ ┴
src └─────────────────────┘ └─────────┘ └┘└────────┘└┘└───────────┘┴ ┴
typ └─────────────────────┘ └─────────┘┴└┘└────────┘└┘└───────────┘┴┴┴
doc └─────────┘ └┘ └┘ ┴ ┴
txt └─────────┘ └┘ └┘ ┴ ┴
par └─────────┘ └┘ └┘ ┴ ┴
pid ┴└──┘└┘ └┘ └┘ ┴ ┴
st └─────────────────────────────────────────┘
3486 else ⟨a::t, cons_sublist_cons _ s, by simp only [cons_append, cons_union, e, insert_of_not_mem h]; split; refl⟩
id ┴ └┘ └───────────────┘ └─────────┘ └────────┘ ┴ └───────────────┘ ┴
src └┘ └───────────────┘ └─────────┘└─────────┘└┘└────────┘└┘ └┘└───────────────┘┴ ┴ └───┘ └──┘
typ ┴ └┘ └───────────────┘ └─────────┘└─────────┘└┘└────────┘└┘┴└┘└───────────────┘┴┴┴ └───┘ └──┘
doc └─────────┘ └┘ └┘ └┘ ┴ ┴ └───┘ └──┘
txt └─────────┘ └┘ └┘ └┘ ┴ ┴ └───┘ └──┘
par └─────────┘ └┘ └┘ └┘ ┴ ┴ └───┘ └──┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ ┴
st └───────────────────────────────────────────────────────────────────────┘
3487
3488 theorem suffix_union_right (l₁ l₂ : list α) : l₂ <:+ l₁ ∪ l₂ :=
id └──┘ ┴ └┘ └─┘ └┘ ┴ └┘
src └──┘ └─┘ ┴
typ └──┘ ┴ └┘ └─┘ └┘ ┴ └┘
doc └─┘
3489 (sublist_suffix_of_union l₁ l₂).imp (λ a, and.right)
id └─────────────────────┘ └┘ └┘ └─┘ ┴ └───────┘
src └─────────────────────┘ └─┘ └───────┘
typ └─────────────────────┘ └┘ └┘ └─┘ ┴ └───────┘
3490
3491 theorem union_sublist_append (l₁ l₂ : list α) : l₁ ∪ l₂ <+ l₁ ++ l₂ :=
id └──┘ ┴ └┘ ┴ └┘ └┘ └┘ └┘ └┘
src └──┘ ┴ └┘ └┘
typ └──┘ ┴ └┘ ┴ └┘ └┘ └┘ └┘ └┘
3492 let ⟨t, s, e⟩ := sublist_suffix_of_union l₁ l₂ in
id └─┘ ┴ ┴ └─────────────────────┘ └┘ └┘
src └─────────────────────┘
typ └─┘ ┴ ┴ └─────────────────────┘ └┘ └┘
3493 e ▸ (append_sublist_append_right _).2 s
id ┴ └─────────────────────────┘ ┴
src ┴ └─────────────────────────┘ ┴
typ ┴ └─────────────────────────┘ ┴
3494
3495 theorem forall_mem_union {p : α → Prop} {l₁ l₂ : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3496 (∀ x ∈ l₁ ∪ l₂, p x) ↔ (∀ x ∈ l₁, p x) ∧ (∀ x ∈ l₂, p x) :=
id ┴ └┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴
src ┴ ┴ ┴
typ ┴ └┘ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴
3497 by simp only [mem_union, or_imp_distrib, forall_and_distrib]
id └───────┘ └────────────┘ └────────────────┘
src └─────────┘└───────┘└┘└────────────┘└┘└────────────────┘└─
typ └─────────┘└───────┘└┘└────────────┘└┘└────────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └──────────────────────────────────────────────────────────
3498
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3499 theorem forall_mem_of_forall_mem_union_left {p : α → Prop} {l₁ l₂ : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3500 (h : ∀ x ∈ l₁ ∪ l₂, p x) : ∀ x ∈ l₁, p x :=
id ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴
src ┴
typ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴
3501 (forall_mem_union.1 h).1
id └──────────────┘┴ ┴ ┴
src └──────────────┘┴ ┴
typ └──────────────┘┴ ┴ ┴
3502
3503 theorem forall_mem_of_forall_mem_union_right {p : α → Prop} {l₁ l₂ : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3504 (h : ∀ x ∈ l₁ ∪ l₂, p x) : ∀ x ∈ l₂, p x :=
id ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴
src ┴
typ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴
3505 (forall_mem_union.1 h).2
id └──────────────┘┴ ┴ ┴
src └──────────────┘┴ ┴
typ └──────────────┘┴ ┴ ┴
3506
3507 end union
3508
3509 /- inter -/
3510 section inter
3511 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
3512
3513 @[simp] theorem inter_nil (l : list α) : [] ∩ l = [] := rfl
id └──┘ ┴ └┘ ┴ ┴ ┴ └┘ └─┘
src └──┘ └┘ ┴ ┴ └┘ └─┘
typ └──┘ ┴ └┘ ┴ ┴ ┴ └┘ └─┘
doc └──┘
3514
3515 @[simp] theorem inter_cons_of_mem {a : α} (l₁ : list α) {l₂ : list α} (h : a ∈ l₂) :
id ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘
src └──┘ └──┘ ┴
typ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘
doc └──┘
3516 (a::l₁) ∩ l₂ = a :: (l₁ ∩ l₂) :=
id ┴└┘└┘ ┴ └┘ ┴ ┴ └┘ └┘ ┴ └┘
src └┘ ┴ ┴ └┘ ┴
typ ┴└┘└┘ ┴ └┘ ┴ ┴ └┘ └┘ ┴ └┘
3517 if_pos h
id └────┘ ┴
src └────┘
typ └────┘ ┴
3518
3519 @[simp] theorem inter_cons_of_not_mem {a : α} (l₁ : list α) {l₂ : list α} (h : a ∉ l₂) :
id ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘
src └──┘ └──┘ ┴
typ ┴ └──┘ ┴ └──┘ ┴ ┴ ┴ └┘
doc └──┘
3520 (a::l₁) ∩ l₂ = l₁ ∩ l₂ :=
id ┴└┘└┘ ┴ └┘ ┴ └┘ ┴ └┘
src └┘ ┴ ┴ ┴
typ ┴└┘└┘ ┴ └┘ ┴ └┘ ┴ └┘
3521 if_neg h
id └────┘ ┴
src └────┘
typ └────┘ ┴
3522
3523 theorem mem_of_mem_inter_left {l₁ l₂ : list α} {a : α} : a ∈ l₁ ∩ l₂ → a ∈ l₁ :=
id └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
src └──┘ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
3524 mem_of_mem_filter
id └───────────────┘
src └───────────────┘
typ └───────────────┘
3525
3526 theorem mem_of_mem_inter_right {l₁ l₂ : list α} {a : α} : a ∈ l₁ ∩ l₂ → a ∈ l₂ :=
id └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
src └──┘ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
3527 of_mem_filter
id └───────────┘
src └───────────┘
typ └───────────┘
3528
3529 theorem mem_inter_of_mem_of_mem {l₁ l₂ : list α} {a : α} : a ∈ l₁ → a ∈ l₂ → a ∈ l₁ ∩ l₂ :=
id └──┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └┘
src └──┘ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └┘
3530 mem_filter_of_mem
id └───────────────┘
src └───────────────┘
typ └───────────────┘
3531
3532 @[simp] theorem mem_inter {a : α} {l₁ l₂ : list α} : a ∈ l₁ ∩ l₂ ↔ a ∈ l₁ ∧ a ∈ l₂ :=
id ┴ └──┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
3533 mem_filter
id └────────┘
src └────────┘
typ └────────┘
3534
3535 theorem inter_subset_left (l₁ l₂ : list α) : l₁ ∩ l₂ ⊆ l₁ :=
id └──┘ ┴ └┘ ┴ └┘ ┴ └┘
src └──┘ ┴ ┴
typ └──┘ ┴ └┘ ┴ └┘ ┴ └┘
3536 filter_subset _
id └───────────┘
src └───────────┘
typ └───────────┘
3537
3538 theorem inter_subset_right (l₁ l₂ : list α) : l₁ ∩ l₂ ⊆ l₂ :=
id └──┘ ┴ └┘ ┴ └┘ ┴ └┘
src └──┘ ┴ ┴
typ └──┘ ┴ └┘ ┴ └┘ ┴ └┘
3539 λ a, mem_of_mem_inter_right
id ┴ └────────────────────┘
src └────────────────────┘
typ ┴ └────────────────────┘
3540
3541 theorem subset_inter {l l₁ l₂ : list α} (h₁ : l ⊆ l₁) (h₂ : l ⊆ l₂) : l ⊆ l₁ ∩ l₂ :=
id └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └┘
src └──┘ ┴ ┴ ┴ ┴
typ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴ ┴ └┘ ┴ └┘
3542 λ a h, mem_inter.2 ⟨h₁ h, h₂ h⟩
id ┴ ┴ └───────┘┴ └┘ ┴ └┘ ┴
src └───────┘┴
typ ┴ ┴ └───────┘┴ └┘ ┴ └┘ ┴
3543
3544 theorem inter_eq_nil_iff_disjoint {l₁ l₂ : list α} : l₁ ∩ l₂ = [] ↔ disjoint l₁ l₂ :=
id └──┘ ┴ └┘ ┴ └┘ ┴ └┘ ┴ └──────┘ └┘ └┘
src └──┘ ┴ ┴ └┘ ┴ └──────┘
typ └──┘ ┴ └┘ ┴ └┘ ┴ └┘ ┴ └──────┘ └┘ └┘
doc └──────┘
3545 by simp only [eq_nil_iff_forall_not_mem, mem_inter, not_and]; refl
id └───────────────────────┘ └───────┘ └─────┘
src └─────────┘└───────────────────────┘└┘└───────┘└┘└─────┘┴ └────
typ └─────────┘└───────────────────────┘└┘└───────┘└┘└─────┘┴ └────
doc └─────────┘ └┘ └┘ ┴ └────
txt └─────────┘ └┘ └┘ ┴ └────
par └─────────┘ └┘ └┘ ┴ └────
pid ┴└──┘└┘ └┘ └┘ ┴ └
st └────────────────────────────────────────────────────────────────
3546
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3547 theorem forall_mem_inter_of_forall_left {p : α → Prop} {l₁ : list α} (h : ∀ x ∈ l₁, p x)
id ┴ └──┘ ┴ ┴ └┘ ┴ ┴
src └──┘
typ ┴ └──┘ ┴ ┴ └┘ ┴ ┴
3548 (l₂ : list α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
3549 ∀ x, x ∈ l₁ ∩ l₂ → p x :=
id ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴
3550 ball.imp_left (λ x, mem_of_mem_inter_left) h
id └───────────┘ ┴ └───────────────────┘ ┴
src └───────────┘ └───────────────────┘
typ └───────────┘ ┴ └───────────────────┘ ┴
3551
3552 theorem forall_mem_inter_of_forall_right {p : α → Prop} (l₁ : list α) {l₂ : list α}
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
3553 (h : ∀ x ∈ l₂, p x) :
id ┴ └┘ ┴ ┴
typ ┴ └┘ ┴ ┴
3554 ∀ x, x ∈ l₁ ∩ l₂ → p x :=
id ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴
3555 ball.imp_left (λ x, mem_of_mem_inter_right) h
id └───────────┘ ┴ └────────────────────┘ ┴
src └───────────┘ └────────────────────┘
typ └───────────┘ ┴ └────────────────────┘ ┴
3556
3557 end inter
3558
3559 /- bag_inter -/
3560 section bag_inter
3561 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
3562
3563 @[simp] theorem nil_bag_inter (l : list α) : [].bag_inter l = [] :=
id └──┘ ┴ └┘└───────┘ ┴ ┴ └┘
src └──┘ └┘└───────┘ ┴ └┘
typ └──┘ ┴ └┘└───────┘ ┴ ┴ └┘
doc └──┘
3564 by cases l; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
3565
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3566 @[simp] theorem bag_inter_nil (l : list α) : l.bag_inter [] = [] :=
id └──┘ ┴ ┴└────────┘ └┘ ┴ └┘
src └──┘ └────────┘ └┘ ┴ └┘
typ └──┘ ┴ ┴└────────┘ └┘ ┴ └┘
doc └──┘
3567 by cases l; refl
id ┴
src └────┘ └────
typ └────┘┴ └────
doc └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
3568
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3569 @[simp] theorem cons_bag_inter_of_pos {a} (l₁ : list α) {l₂} (h : a ∈ l₂) :
id └──┘ ┴ ┴ ┴ └┘
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ └┘
doc └──┘
3570 (a :: l₁).bag_inter l₂ = a :: l₁.bag_inter (l₂.erase a) :=
id ┴ └┘ └┘ └───────┘ └┘ ┴ ┴ └┘ └┘└────────┘ └┘└────┘ ┴
src └┘ └───────┘ ┴ └┘ └────────┘ └────┘
typ ┴ └┘ └┘ └───────┘ └┘ ┴ ┴ └┘ └┘└────────┘ └┘└────┘ ┴
3571 by cases l₂; exact if_pos h
id └┘ └────┘ ┴
src └────┘ └────┘└────┘┴ └
typ └────┘└┘ └────┘└────┘┴┴└
doc └────┘ └────┘ ┴ └
txt └────┘ └────┘ ┴ └
par └────┘ └────┘ ┴ └
pid ┴ ┴ ┴ └
st └─────────────────────────
3572
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3573 @[simp] theorem cons_bag_inter_of_neg {a} (l₁ : list α) {l₂} (h : a ∉ l₂) :
id └──┘ ┴ ┴ ┴ └┘
src └──┘ ┴
typ └──┘ ┴ ┴ ┴ └┘
doc └──┘
3574 (a :: l₁).bag_inter l₂ = l₁.bag_inter l₂ :=
id ┴ └┘ └┘ └───────┘ └┘ ┴ └┘└────────┘ └┘
src └┘ └───────┘ ┴ └────────┘
typ ┴ └┘ └┘ └───────┘ └┘ ┴ └┘└────────┘ └┘
3575 begin
st └─────
3576 cases l₂, {simp only [bag_inter_nil]},
id └┘ └───────────┘
src └────┘ └─────────┘└───────────┘┴
typ └────┘└┘ └─────────┘└───────────┘┴
doc └────┘ └─────────┘ ┴
txt └────┘ └─────────┘ ┴
par └────┘ └─────────┘ ┴
pid ┴ ┴└──┘└┘ ┴
st ─────────┘└──────────────────────────┘└┘└
3577 simp only [erase_of_not_mem h, list.bag_inter, if_neg h]
id └──────────────┘ ┴ └────────────┘ └────┘ ┴
src └─────────┘└──────────────┘┴ └┘└────────────┘└┘└────┘┴ └┘
typ └─────────┘└──────────────┘┴┴└┘└────────────┘└┘└────┘┴┴└┘
doc └─────────┘ ┴ └┘ └┘ ┴ └┘
txt └─────────┘ ┴ └┘ └┘ ┴ └┘
par └─────────┘ ┴ └┘ └┘ ┴ └┘
pid ┴└──┘└┘ ┴ └┘ └┘ ┴ ┴┴
st ──────────────────────────────────────────────────────────┘
3578 end
st └─┘
3579
3580 @[simp] theorem mem_bag_inter {a : α} : ∀ {l₁ l₂ : list α}, a ∈ l₁.bag_inter l₂ ↔ a ∈ l₁ ∧ a ∈ l₂
id ┴ ┴ └──┘ ┴ ┴ ┴ └┘└────────┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src └──┘ ┴ └────────┘ ┴ ┴ ┴ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ └┘└────────┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
doc └──┘
3581 | [] l₂ := by simp only [nil_bag_inter, not_mem_nil, false_and]
id └┘ └───────────┘ └─────────┘ └───────┘
src └┘ └─────────┘└───────────┘└┘└─────────┘└┘└───────┘└┘
typ └┘ └─────────┘└───────────┘└┘└─────────┘└┘└───────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st └─────────────────────────────────────────────────┘
3582 | (b::l₁) l₂ := begin
id └┘
src └┘
typ └┘
st └─────
3583 by_cases b ∈ l₂,
id ┴ ┴ └┘
src └───────┘ ┴┴┴
typ └───────┘┴┴┴┴└┘
doc └───────┘ ┴ ┴
txt └───────┘ ┴ ┴
par └───────┘ ┴ ┴
pid ┴ ┴ ┴
st ──────────────────┘└─
3584 { rw [cons_bag_inter_of_pos _ h, mem_cons_iff, mem_cons_iff, mem_bag_inter],
id └───────────────────┘ ┴ └──────────┘ └──────────┘
src └──┘└───────────────────┘└─┘ └┘└──────────┘└┘└──────────┘└┘ ┴
typ └──┘└───────────────────┘└─┘┴└┘└──────────┘└┘└──────────┘└┘└───────────┘┴
doc └──┘ └─┘ └┘ └┘ └┘ ┴
txt └──┘ └─┘ └┘ └┘ └┘ ┴
par └──┘ └─┘ └┘ └┘ └┘ ┴
pid └┘ └─┘ └┘ └┘ └┘ ┴
st ─────┘└───────────────────────────┘└────────────┘└────────────┘└─────────────┘└──
3585 by_cases ba : a = b,
id ┴ ┴ ┴
src └───────┘ └─┘ ┴┴┴
typ └───────┘ └─┘┴┴┴┴┴
doc └───────┘ └─┘ ┴ ┴
txt └───────┘ └─┘ ┴ ┴
par └───────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ────────────────────────┘└─
3586 { simp only [ba, h, eq_self_iff_true, true_or, true_and] },
id └┘ ┴ └──────────────┘ └─────┘ └──────┘
src └─────────┘ └┘ └┘└──────────────┘└┘└─────┘└┘└──────┘└┘
typ └─────────┘└┘└┘┴└┘└──────────────┘└┘└─────┘└┘└──────┘└┘
doc └─────────┘ └┘ └┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴┴
st ───────┘└─────────────────────────────────────────────────────┘└┘└
3587 { simp only [mem_erase_of_ne ba, ba, false_or] } },
id └─────────────┘ └┘ └┘ └──────┘
src └─────────┘└─────────────┘┴ └┘ └┘└──────┘└┘
typ └─────────┘└─────────────┘┴└┘└┘└┘└┘└──────┘└┘
doc └─────────┘ ┴ └┘ └┘ └┘
txt └─────────┘ ┴ └┘ └┘ └┘
par └─────────┘ ┴ └┘ └┘ └┘
pid ┴└──┘└┘ ┴ └┘ └┘ ┴┴
st ────────────────────────────────────────────────────┘└──┘└
3588 { rw [cons_bag_inter_of_neg _ h, mem_bag_inter, mem_cons_iff, or_and_distrib_right],
id └───────────────────┘ ┴ └──────────┘ └──────────────────┘
src └──┘└───────────────────┘└─┘ └┘ └┘└──────────┘└┘└──────────────────┘┴
typ └──┘└───────────────────┘└─┘┴└┘└───────────┘└┘└──────────┘└┘└──────────────────┘┴
doc └──┘ └─┘ └┘ └┘ └┘ ┴
txt └──┘ └─┘ └┘ └┘ └┘ ┴
par └──┘ └─┘ └┘ └┘ └┘ ┴
pid └┘ └─┘ └┘ └┘ └┘ ┴
st ──────────────────────────────────┘└─────────────┘└────────────┘└────────────────────┘└──
3589 symmetry, apply or_iff_right_of_imp,
id └─────────────────┘
src └──────┘ └────┘└─────────────────┘
typ └──────┘ └────┘└─────────────────┘
doc └──────┘ └────┘
txt └──────┘ └────┘
par └──────┘ └────┘
pid ┴
st ─────────────┘└─────────────────────────┘└─
3590 rintro ⟨rfl, h'⟩, exact h.elim h' }
id └────┘ └┘
src └──────────────┘ └────┘└────┘┴ ┴
typ └──────────────┘ └────┘└────┘┴└┘┴
doc └──────────────┘ └────┘ ┴ ┴
txt └──────────────┘ └────┘ ┴ ┴
par └──────────────┘ └────┘ ┴ ┴
pid └────────┘ ┴ ┴ ┴
st ─────────────────────┘└────────────────┘└─
3591 end
st ────┘
3592
3593 @[simp] theorem count_bag_inter {a : α} :
id ┴
typ ┴
doc └──┘
3594 ∀ {l₁ l₂ : list α}, count a (l₁.bag_inter l₂) = min (count a l₁) (count a l₂)
id ┴ └──┘ ┴ └───┘ ┴ └┘└────────┘ └┘ ┴ └─┘ └───┘ ┴ └┘ └───┘ ┴ └┘
src └──┘ └───┘ └────────┘ ┴ └─┘ └───┘ └───┘
typ ┴ └──┘ ┴ └───┘ ┴ └┘└────────┘ └┘ ┴ └─┘ └───┘ ┴ └┘ └───┘ ┴ └┘
doc └───┘ └───┘ └───┘
3595 | [] l₂ := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
3596 | l₁ [] := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
3597 | (h₁ :: l₁) (h₂ :: l₂) :=
id └┘ └┘
src └┘ └┘
typ └┘ └┘
3598 begin
st └─────
3599 simp only [list.bag_inter, list.mem_cons_iff],
id └────────────┘ └───────────────┘
src └─────────┘└────────────┘└┘└───────────────┘┴
typ └─────────┘└────────────┘└┘└───────────────┘┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st ──────────────────────────────────────────────┘└─
3600 by_cases p₁ : h₂ = h₁; by_cases p₂ : h₁ = a,
id └┘ ┴ └┘ └┘ ┴
src └───────┘ └─┘ ┴┴┴ └───────┘ └─┘ ┴ ┴
typ └───────┘ └─┘└┘┴┴┴└┘ └───────┘ └─┘└┘┴ ┴┴
doc └───────┘ └─┘ ┴ ┴ └───────┘ └─┘ ┴ ┴
txt └───────┘ └─┘ ┴ ┴ └───────┘ └─┘ ┴ ┴
par └───────┘ └─┘ ┴ ┴ └───────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
st ────────────────────────────────────────────┘└─
3601 { simp only [p₁, p₂, count_bag_inter, min_succ_succ, erase_cons_head, if_true, mem_cons_iff,
id └┘ └┘ └───────────┘ └─────────────┘ └─────┘ └──────────┘
src └─────────┘ └┘ └┘ └┘└───────────┘└┘└─────────────┘└┘└─────┘└┘└──────────┘└─
typ └─────────┘└┘└┘└┘└┘└─────────────┘└┘└───────────┘└┘└─────────────┘└┘└─────┘└┘└──────────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
st ───┘└──────────────────────────────────────────────────────────────────────────────────────────
3602 count_cons_self, true_or, eq_self_iff_true] },
id └─────────────┘ └─────┘ └──────────────┘
src ──────────────┘└─────────────┘└┘└─────┘└┘└──────────────┘└┘
typ ──────────────┘└─────────────┘└┘└─────┘└┘└──────────────┘└┘
doc ──────────────┘ └┘ └┘ └┘
txt ──────────────┘ └┘ └┘ └┘
par ──────────────┘ └┘ └┘ └┘
pid ──────────────┘ └┘ └┘ ┴┴
st ──────────────────────────────────────────────────────────┘└┘└
3603 { simp only [p₁, ne.symm p₂, count_bag_inter, count_cons, erase_cons_head, if_true, mem_cons_iff,
id └┘ └─────┘ └┘ └────────┘ └─────────────┘ └─────┘ └──────────┘
src └─────────┘ └┘└─────┘┴ └┘ └┘└────────┘└┘└─────────────┘└┘└─────┘└┘└──────────┘└─
typ └─────────┘└┘└┘└─────┘┴└┘└┘└─────────────┘└┘└────────┘└┘└─────────────┘└┘└─────┘└┘└──────────┘└─
doc └─────────┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ └─
st ───┘└───────────────────────────────────────────────────────────────────────────────────────────────
3604 true_or, eq_self_iff_true, if_false] },
id └─────┘ └──────────────┘ └──────┘
src ──────────────┘└─────┘└┘└──────────────┘└┘└──────┘└┘
typ ──────────────┘└─────┘└┘└──────────────┘└┘└──────┘└┘
doc ──────────────┘ └┘ └┘ └┘
txt ──────────────┘ └┘ └┘ └┘
par ──────────────┘ └┘ └┘ └┘
pid ──────────────┘ └┘ └┘ ┴┴
st ───────────────────────────────────────────────────┘└┘└
3605 { rw p₂ at p₁,
id └┘
src └─┘ └────┘
typ └─┘└┘└────┘
doc └─┘ └────┘
txt └─┘ └────┘
par └─┘ └────┘
pid ┴ └────┘
st ───┘└─────────┘└─
3606 by_cases p₃ : a ∈ l₂,
id ┴ ┴ └┘
src └───────┘ └─┘ ┴┴┴
typ └───────┘ └─┘┴┴┴┴└┘
doc └───────┘ └─┘ ┴ ┴
txt └───────┘ └─┘ ┴ ┴
par └───────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ───────────────────────┘└─
3607 { simp only [p₁, ne.symm p₁, p₂, p₃, erase_cons, count_bag_inter, eq.symm (min_succ_succ _ _),
id └┘ └─────┘ └┘ └┘ └┘ └────────┘ └─────┘ └───────────┘
src └─────────┘ └┘└─────┘┴ └┘ └┘ └┘└────────┘└┘ └┘└─────┘┴ └───────────┘└──────
typ └─────────┘└┘└┘└─────┘┴└┘└┘└┘└┘└┘└┘└────────┘└┘└─────────────┘└┘└─────┘┴ └───────────┘└──────
doc └─────────┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ ┴ └──────
txt └─────────┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ ┴ └──────
par └─────────┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ ┴ └──────
pid ┴└──┘└┘ └┘ ┴ └┘ └┘ └┘ └┘ └┘ ┴ └──────
st ─────┘└────────────────────────────────────────────────────────────────────────────────────────────
3608 succ_pred_eq_of_pos (count_pos.2 p₃), if_true, mem_cons_iff, false_or,
id └─────────────────┘ └───────┘ └┘ └─────┘ └──────────┘ └──────┘
src ────────────────┘└─────────────────┘┴ └───────┘└─┘ └─┘└─────┘└┘└──────────┘└┘└──────┘└─
typ ────────────────┘└─────────────────┘┴ └───────┘└─┘└┘└─┘└─────┘└┘└──────────┘└┘└──────┘└─
doc ────────────────┘ ┴ └─┘ └─┘ └┘ └┘ └─
txt ────────────────┘ ┴ └─┘ └─┘ └┘ └┘ └─
par ────────────────┘ ┴ └─┘ └─┘ └┘ └┘ └─
pid ────────────────┘ ┴ └─┘ └─┘ └┘ └┘ └─
st ────────────────────────────────────────────────────────────────────────────────────────
3609 count_cons_self, eq_self_iff_true, if_false, ne.def, not_false_iff,
id └─────────────┘ └──────────────┘ └──────┘ └────┘ └───────────┘
src ────────────────┘└─────────────┘└┘└──────────────┘└┘└──────┘└┘└────┘└┘└───────────┘└─
typ ────────────────┘└─────────────┘└┘└──────────────┘└┘└──────┘└┘└────┘└┘└───────────┘└─
doc ────────────────┘ └┘ └┘ └┘ └┘ └─
txt ────────────────┘ └┘ └┘ └┘ └┘ └─
par ────────────────┘ └┘ └┘ └┘ └┘ └─
pid ────────────────┘ └┘ └┘ └┘ └┘ └─
st ─────────────────────────────────────────────────────────────────────────────────────
3610 count_erase_self, list.count_cons_of_ne] },
id └──────────────┘ └───────────────────┘
src ────────────────┘└──────────────┘└┘└───────────────────┘└┘
typ ────────────────┘└──────────────┘└┘└───────────────────┘└┘
doc ────────────────┘ └┘ └┘
txt ────────────────┘ └┘ └┘
par ────────────────┘ └┘ └┘
pid ────────────────┘ └┘ ┴┴
st ─────────────────────────────────────────────────────────┘└┘└
3611 { simp [ne.symm p₁, p₂, p₃] } },
id └─────┘ └┘ └┘ └┘
src └────┘└─────┘┴ └┘ └┘ └┘
typ └────┘└─────┘┴└┘└┘└┘└┘└┘└┘
doc └────┘ ┴ └┘ └┘ └┘
txt └────┘ ┴ └┘ └┘ └┘
par └────┘ ┴ └┘ └┘ └┘
pid ┴┴ ┴ └┘ └┘ ┴┴
st ───────────────────────────────┘└──┘└
3612 { by_cases p₄ : h₁ ∈ l₂; simp only [ne.symm p₁, ne.symm p₂, p₄, count_bag_inter, if_true, if_false,
id └┘ └┘ └─────┘ └┘ └─────┘ └┘ └┘ └─────┘ └──────┘
src └───────┘ └─┘ ┴ ┴ └─────────┘└─────┘┴ └┘└─────┘┴ └┘ └┘ └┘└─────┘└┘└──────┘└─
typ └───────┘ └─┘└┘┴ ┴└┘ └─────────┘└─────┘┴└┘└┘└─────┘┴└┘└┘└┘└┘└─────────────┘└┘└─────┘└┘└──────┘└─
doc └───────┘ └─┘ ┴ ┴ └─────────┘ ┴ └┘ ┴ └┘ └┘ └┘ └┘ └─
txt └───────┘ └─┘ ┴ ┴ └─────────┘ ┴ └┘ ┴ └┘ └┘ └┘ └┘ └─
par └───────┘ └─┘ ┴ ┴ └─────────┘ ┴ └┘ ┴ └┘ └┘ └┘ └┘ └─
pid ┴ └─┘ ┴ ┴ ┴└──┘└┘ ┴ └┘ ┴ └┘ └┘ └┘ └┘ └─
st ──────────────────────────────────────────────────────────────────────────────────────────────────────
3613 mem_cons_iff, false_or, eq_self_iff_true, ne.def, not_false_iff,count_erase_of_ne, count_cons_of_ne] }
id └──────────┘ └──────┘ └──────────────┘ └────┘ └───────────┘ └───────────────┘ └──────────────┘
src ─────┘└──────────┘└┘└──────┘└┘└──────────────┘└┘└────┘└┘└───────────┘┴└───────────────┘└┘└──────────────┘└┘
typ ─────┘└──────────┘└┘└──────┘└┘└──────────────┘└┘└────┘└┘└───────────┘┴└───────────────┘└┘└──────────────┘└┘
doc ─────┘ └┘ └┘ └┘ └┘ ┴ └┘ └┘
txt ─────┘ └┘ └┘ └┘ └┘ ┴ └┘ └┘
par ─────┘ └┘ └┘ └┘ └┘ ┴ └┘ └┘
pid ─────┘ └┘ └┘ └┘ └┘ ┴ └┘ ┴┴
st ──────────────────────────────────────────────────────────────────────────────────────────────────────────┘└─
3614 end
st ──┘
3615
3616 theorem bag_inter_sublist_left : ∀ l₁ l₂ : list α, l₁.bag_inter l₂ <+ l₁
id └┘ └──┘ ┴ └┘└────────┘ └┘ └┘ └┘
src └──┘ └────────┘ └┘
typ └┘ └──┘ ┴ └┘└────────┘ └┘ └┘ └┘
3617 | [] l₂ := by simp [nil_sublist]
id └┘ └─────────┘
src └┘ └────┘└─────────┘└┘
typ └┘ └────┘└─────────┘└┘
doc └────┘ └┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st └──────────────────┘
3618 | (b::l₁) l₂ := begin
id └┘
src └┘
typ └┘
st └─────
3619 by_cases b ∈ l₂; simp [h],
id ┴ ┴ └┘ ┴
src └───────┘ ┴┴┴ └────┘ ┴
typ └───────┘┴┴┴┴└┘ └────┘┴┴
doc └───────┘ ┴ ┴ └────┘ ┴
txt └───────┘ ┴ ┴ └────┘ ┴
par └───────┘ ┴ ┴ └────┘ ┴
pid ┴ ┴ ┴ ┴┴ ┴
st ──────────────────────────┘└─
3620 { apply cons_sublist_cons, apply bag_inter_sublist_left },
id └───────────────┘
src └────┘└───────────────┘ └────┘ ┴
typ └────┘└───────────────┘ └────┘ ┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ───┘└─────────────────────┘└─────────────────────────────┘└┘└
3621 { apply sublist_cons_of_sublist, apply bag_inter_sublist_left }
id └─────────────────────┘
src └────┘└─────────────────────┘ └────┘ ┴
typ └────┘└─────────────────────┘ └────┘ ┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴ ┴
st ────────────────────────────────┘└─────────────────────────────┘└─
3622 end
st ──┘
3623
3624 theorem bag_inter_nil_iff_inter_nil : ∀ l₁ l₂ : list α, l₁.bag_inter l₂ = [] ↔ l₁ ∩ l₂ = []
id └┘ └──┘ ┴ └┘└────────┘ └┘ ┴ └┘ ┴ └┘ ┴ └┘ ┴ └┘
src └──┘ └────────┘ ┴ └┘ ┴ ┴ ┴ └┘
typ └┘ └──┘ ┴ └┘└────────┘ └┘ ┴ └┘ ┴ └┘ ┴ └┘ ┴ └┘
3625 | [] l₂ := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
3626 | (b::l₁) l₂ :=
id └┘
src └┘
typ └┘
3627 begin
st └─────
3628 by_cases h : b ∈ l₂; simp [h],
id ┴ ┴ └┘ ┴
src └───────┘ └─┘ ┴┴┴ └────┘ ┴
typ └───────┘ └─┘┴┴┴┴└┘ └────┘┴┴
doc └───────┘ └─┘ ┴ ┴ └────┘ ┴
txt └───────┘ └─┘ ┴ ┴ └────┘ ┴
par └───────┘ └─┘ ┴ ┴ └────┘ ┴
pid ┴ └─┘ ┴ ┴ ┴┴ ┴
st ──────────────────────────────┘└─
3629 exact bag_inter_nil_iff_inter_nil l₁ l₂
id └─────────────────────────┘ └┘ └┘
src └────┘ ┴ ┴ ┴
typ └────┘└─────────────────────────┘┴└┘┴└┘┴
doc └────┘ ┴ ┴ ┴
txt └────┘ ┴ ┴ ┴
par └────┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ─────────────────────────────────────────┘
3630 end
st └─┘
3631
3632 end bag_inter
3633
3634 /- pairwise relation (generalized no duplicate) -/
3635
3636 section pairwise
3637
3638 run_cmd tactic.mk_iff_of_inductive_prop `list.pairwise `list.pairwise_iff
id └─────────────────────────────┘ ┴ ┴
src └─────────────────────────────┘ ┴ ┴
typ └─────────────────────────────┘ ┴ ┴
doc └─────────────────────────────┘
3639
3640 variable {R : α → α → Prop}
id ┴
typ ┴
3641
3642 theorem rel_of_pairwise_cons {a : α} {l : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3643 (p : pairwise R (a::l)) : ∀ {a'}, a' ∈ l → R a a' :=
id └──────┘ ┴ ┴└┘┴ └┘ └┘ ┴ ┴ ┴ ┴ └┘
src └──────┘ └┘ ┴
typ └──────┘ ┴ ┴└┘┴ └┘ └┘ ┴ ┴ ┴ ┴ └┘
doc └──────┘
3644 (pairwise_cons.1 p).1
id └───────────┘┴ ┴ ┴
src └───────────┘┴ ┴
typ └───────────┘┴ ┴ ┴
3645
3646 theorem pairwise_of_pairwise_cons {a : α} {l : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3647 (p : pairwise R (a::l)) : pairwise R l :=
id └──────┘ ┴ ┴└┘┴ └──────┘ ┴ ┴
src └──────┘ └┘ └──────┘
typ └──────┘ ┴ ┴└┘┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
3648 (pairwise_cons.1 p).2
id └───────────┘┴ ┴ ┴
src └───────────┘┴ ┴
typ └───────────┘┴ ┴ ┴
3649
3650 theorem pairwise.imp_of_mem {S : α → α → Prop} {l : list α}
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
3651 (H : ∀ {a b}, a ∈ l → b ∈ l → R a b → S a b) (p : pairwise R l) : pairwise S l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴ ┴
src ┴ ┴ └──────┘ └──────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
3652 begin
st └─────
3653 induction p with a l r p IH generalizing H; constructor,
id ┴
src └────────┘ └─────────────────────────────┘ └─────────┘
typ └────────┘┴└─────────────────────────────┘ └─────────┘
doc └────────┘ └─────────────────────────────┘ └─────────┘
txt └────────┘ └─────────────────────────────┘ └─────────┘
par └────────┘ └─────────────────────────────┘ └─────────┘
pid ┴ ┴└─────────────┘└─────────────┘
st ────────────────────────────────────────────────────────┘└─
3654 { exact ball.imp_right
id └────────────┘
src └────┘└────────────┘└
typ └────┘└────────────┘└
doc └────┘ └
txt └────┘ └
par └────┘ └
pid ┴ └
st ───┘└────────────────────
3655 (λ x h, H (mem_cons_self _ _) (mem_cons_of_mem _ h)) r },
id ┴ └───────────┘ └─────────────┘ ┴
src ─────┘ └────┘ ┴ └───────────┘└────┘ └─────────────┘└─┘ └─┘ ┴
typ ─────┘ └────┘┴┴ └───────────┘└────┘ └─────────────┘└─┘ └─┘┴┴
doc ─────┘ └────┘ ┴ └────┘ └─┘ └─┘ ┴
txt ─────┘ └────┘ ┴ └────┘ └─┘ └─┘ ┴
par ─────┘ └────┘ ┴ └────┘ └─┘ └─┘ ┴
pid ─────┘ └────┘ ┴ └────┘ └─┘ └─┘ ┴
st ────────────────────────────────────────────────────────────┘└┘└
3656 { exact IH (λ a b m m', H
id └┘ ┴
src └────┘ ┴ └─────────┘ └
typ └────┘└┘┴ └─────────┘┴└
doc └────┘ ┴ └─────────┘ └
txt └────┘ ┴ └─────────┘ └
par └────┘ ┴ └─────────┘ └
pid ┴ ┴ └─────────┘ └
st ────────────────────────────
3657 (mem_cons_of_mem _ m) (mem_cons_of_mem _ m')) }
id └─────────────┘
src ─────┘ └─┘ └┘ └─────────────┘└─┘ └─┘
typ ─────┘ └─┘ └┘ └─────────────┘└─┘ └─┘
doc ─────┘ └─┘ └┘ └─┘ └─┘
txt ─────┘ └─┘ └┘ └─┘ └─┘
par ─────┘ └─┘ └┘ └─┘ └─┘
pid ─────┘ └─┘ └┘ └─┘ └┘┴
st ───────────────────────────────────────────────────┘└─
3658 end
st ──┘
3659
3660 theorem pairwise.imp {S : α → α → Prop}
id ┴ ┴
typ ┴ ┴
3661 (H : ∀ a b, R a b → S a b) {l : list α} : pairwise R l → pairwise S l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ └──────┘ ┴ ┴
src └──┘ └──────┘ └──────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
3662 pairwise.imp_of_mem (λ a b _ _, H a b)
id └─────────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └─────────────────┘
typ └─────────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
3663
3664 theorem pairwise.and {S : α → α → Prop} {l : list α} :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
3665 pairwise (λ a b, R a b ∧ S a b) l ↔ pairwise R l ∧ pairwise S l :=
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
src └──────┘ ┴ ┴ └──────┘ ┴ └──────┘
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘ └──────┘
3666 ⟨λ h, ⟨h.imp (λ a b h, h.1), h.imp (λ a b h, h.2)⟩,
id ┴ ┴└──┘ ┴ ┴ ┴ ┴┴ ┴└──┘ ┴ ┴ ┴ ┴┴
src └──┘ ┴ └──┘ ┴
typ ┴ ┴└──┘ ┴ ┴ ┴ ┴┴ ┴└──┘ ┴ ┴ ┴ ┴┴
3667 λ ⟨hR, hS⟩, begin
id ┴
typ ┴
st └─────
3668 clear_, induction hR with a l R1 R2 IH;
id └┘
src └────┘ └────────┘ └────────────────┘
typ └────┘ └────────┘└┘└────────────────┘
doc └────┘ └────────┘ └────────────────┘
txt └────┘ └────────┘ └────────────────┘
par └────┘ └────────┘ └────────────────┘
pid ┴ ┴└───────────────┘
st ───────┘└─────────────────────────────────
3669 simp only [pairwise.nil, pairwise_cons] at *,
id └──────────┘ └───────────┘
src └─────────┘└──────────┘└┘└───────────┘└────┘
typ └─────────┘└──────────┘└┘└───────────┘└────┘
doc └─────────┘ └┘ └────┘
txt └─────────┘ └┘ └────┘
par └─────────┘ └┘ └────┘
pid ┴└──┘└┘ └┘ ┴┴└──┘
st ─────────────────────────────────────────────┘└─
3670 exact ⟨λ b bl, ⟨R1 b bl, hS.1 b bl⟩, IH hS.2⟩
id └┘ └┘ └┘
src └────┘ └─────┘ ┴ ┴ └┘ └─┘ ┴ └─┘ ┴ └───
typ └────┘ └─────┘ └┘┴ ┴ └┘ └─┘ ┴ └─┘└┘┴└┘└───
doc └────┘ └─────┘ ┴ ┴ └┘ └─┘ ┴ └─┘ ┴ └───
txt └────┘ └─────┘ ┴ ┴ └┘ └─┘ ┴ └─┘ ┴ └───
par └────┘ └─────┘ ┴ ┴ └┘ └─┘ ┴ └─┘ ┴ └───
pid ┴ └─────┘ ┴ ┴ └┘ └─┘ ┴ └─┘ ┴ └─┘└
st ────────────────────────────────────────────────
3671 end⟩
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘└─┘
3672
3673 theorem pairwise.imp₂ {S : α → α → Prop} {T : α → α → Prop}
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
3674 (H : ∀ a b, R a b → S a b → T a b) {l : list α}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
3675 (hR : pairwise R l) (hS : pairwise S l) : pairwise T l :=
id └──────┘ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴ ┴
src └──────┘ └──────┘ └──────┘
typ └──────┘ ┴ ┴ └──────┘ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘ └──────┘
3676 (pairwise.and.2 ⟨hR, hS⟩).imp $ λ a b, and.rec (H a b)
id └──────────┘┴ └┘ └┘ └─┘ ┴ ┴ └─────┘ ┴ ┴ ┴
src └──────────┘┴ └─┘ └─────┘
typ └──────────┘┴ └┘ └┘ └─┘ ┴ ┴ └─────┘ ┴ ┴ ┴
3677
3678 theorem pairwise.iff_of_mem {S : α → α → Prop} {l : list α}
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
3679 (H : ∀ {a b}, a ∈ l → b ∈ l → (R a b ↔ S a b)) : pairwise R l ↔ pairwise S l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
src ┴ ┴ ┴ └──────┘ ┴ └──────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
3680 ⟨pairwise.imp_of_mem (λ a b m m', (H m m').1),
id └─────────────────┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴
src └─────────────────┘ ┴
typ └─────────────────┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴
3681 pairwise.imp_of_mem (λ a b m m', (H m m').2)⟩
id └─────────────────┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴
src └─────────────────┘ ┴
typ └─────────────────┘ ┴ ┴ ┴ └┘ ┴ ┴ └┘ ┴
3682
3683 theorem pairwise.iff {S : α → α → Prop}
id ┴ ┴
typ ┴ ┴
3684 (H : ∀ a b, R a b ↔ S a b) {l : list α} : pairwise R l ↔ pairwise S l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
src ┴ └──┘ └──────┘ ┴ └──────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
3685 pairwise.iff_of_mem (λ a b _ _, H a b)
id └─────────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └─────────────────┘
typ └─────────────────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
3686
3687 theorem pairwise_of_forall {l : list α} (H : ∀ x y, R x y) : pairwise R l :=
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴
src └──┘ └──────┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘
3688 by induction l; [exact pairwise.nil,
id ┴ ┴ └──────────┘
src └────────┘ ┴└────┘└──────────┘
typ └────────┘┴ ┴└────┘└──────────┘
doc └────────┘ └────┘
txt └────────┘ └────┘
par └────────┘ └────┘
pid ┴ ┴
st └──────────────────────────────────
3689 simp only [*, pairwise_cons, forall_2_true_iff, and_true]]
id └───────────┘ └───────────────┘ └──────┘
src └────────────┘└───────────┘└┘└───────────────┘└┘└──────┘┴
typ └────────────┘└───────────┘└┘└───────────────┘└┘└──────┘┴
doc └────────────┘ └┘ └┘ ┴
txt └────────────┘ └┘ └┘ ┴
par └────────────┘ └┘ └┘ ┴
pid ┴└──┘└───┘ └┘ └┘ ┴
st ─────────────────────────────────────────────────────────┘
3690
3691 theorem pairwise.and_mem {l : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
3692 pairwise R l ↔ pairwise (λ x y, x ∈ l ∧ y ∈ l ∧ R x y) l :=
id └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ ┴ └──────┘ ┴ ┴ ┴ ┴
typ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘ └──────┘
3693 pairwise.iff_of_mem (by simp only [true_and, iff_self, forall_2_true_iff] {contextual := tt})
id └─────────────────┘ └──────┘ └──────┘ └───────────────┘ └┘
src └─────────────────┘ └─────────┘└──────┘└┘└──────┘└┘└───────────────┘└┘ └────────────┘└┘┴
typ └─────────────────┘ └─────────┘└──────┘└┘└──────┘└┘└───────────────┘└┘ └────────────┘└┘┴
doc └─────────┘ └┘ └┘ └┘ └────────────┘ ┴
txt └─────────┘ └┘ └┘ └┘ └────────────┘ ┴
par └─────────┘ └┘ └┘ └┘ └────────────┘ ┴
pid ┴└──┘└┘ └┘ └┘ ┴┴ └────────────┘ ┴
st └───────────────────────────────────────────────────────────────────┘
3694
3695 theorem pairwise.imp_mem {l : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
3696 pairwise R l ↔ pairwise (λ x y, x ∈ l → y ∈ l → R x y) l :=
id └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ ┴ └──────┘ ┴ ┴
typ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘ └──────┘
3697 pairwise.iff_of_mem (by simp only [forall_prop_of_true, iff_self, forall_2_true_iff] {contextual := tt})
id └─────────────────┘ └─────────────────┘ └──────┘ └───────────────┘ └┘
src └─────────────────┘ └─────────┘└─────────────────┘└┘└──────┘└┘└───────────────┘└┘ └────────────┘└┘┴
typ └─────────────────┘ └─────────┘└─────────────────┘└┘└──────┘└┘└───────────────┘└┘ └────────────┘└┘┴
doc └─────────┘ └┘ └┘ └┘ └────────────┘ ┴
txt └─────────┘ └┘ └┘ └┘ └────────────┘ ┴
par └─────────┘ └┘ └┘ └┘ └────────────┘ ┴
pid ┴└──┘└┘ └┘ └┘ ┴┴ └────────────┘ ┴
st └──────────────────────────────────────────────────────────────────────────────┘
3698
3699 theorem pairwise_of_sublist : Π {l₁ l₂ : list α}, l₁ <+ l₂ → pairwise R l₂ → pairwise R l₁
id ┴ └──┘ ┴ └┘ └┘ └┘ └──────┘ ┴ └┘ └──────┘ ┴ └┘
src └──┘ └┘ └──────┘ └──────┘
typ ┴ └──┘ ┴ └┘ └┘ └┘ └──────┘ ┴ └┘ └──────┘ ┴ └┘
doc └──────┘ └──────┘
3700 | ._ ._ sublist.slnil h := h
id └───────────┘ ┴
src └───────────┘
typ └───────────┘ ┴
3701 | ._ ._ (sublist.cons l₁ l₂ a s) (pairwise.cons i n) := pairwise_of_sublist s n
id └──────────┘ ┴ └───────────┘ ┴ └─────────────────┘
src └──────────┘ └───────────┘
typ └──────────┘ ┴ └───────────┘ ┴ └─────────────────┘
3702 | ._ ._ (sublist.cons2 l₁ l₂ a s) (pairwise.cons i n) :=
id └───────────┘ ┴ └───────────┘ ┴ ┴
src └───────────┘ └───────────┘
typ └───────────┘ ┴ └───────────┘ ┴ ┴
3703 (pairwise_of_sublist s n).cons (ball.imp_left (subset_of_sublist s) i)
id └─────────────────┘ └──┘ └───────────┘ └───────────────┘
src └──┘ └───────────┘ └───────────────┘
typ └─────────────────┘ └──┘ └───────────┘ └───────────────┘
3704
3705 theorem forall_of_forall_of_pairwise (H : symmetric R)
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
3706 {l : list α} (H₁ : ∀ x ∈ l, R x x) (H₂ : pairwise R l) :
id └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴
src └──┘ └──────┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘
3707 ∀ (x ∈ l) (y ∈ l), R x y :=
id ┴┴ ┴ ┴ ┴ ┴ ┴ ┴
typ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴
3708 begin
st └─────
3709 induction l with a l IH, { exact forall_mem_nil _ },
id ┴ └────────────┘
src └────────┘ └──────────┘ └────┘└────────────┘└─┘
typ └────────┘┴└──────────┘ └────┘└────────────┘└─┘
doc └────────┘ └──────────┘ └────┘ └─┘
txt └────────┘ └──────────┘ └────┘ └─┘
par └────────┘ └──────────┘ └────┘ └─┘
pid ┴ ┴└─────────┘ ┴ └┘┴
st ────────────────────────┘└──┘└─────────────────────┘└┘└
3710 cases forall_mem_cons.1 H₁ with H₁₁ H₁₂,
id └─────────────┘ └┘
src └────┘└─────────────┘└─┘ └───────────┘
typ └────┘└─────────────┘└─┘└┘└───────────┘
doc └────┘ └─┘ └───────────┘
txt └────┘ └─┘ └───────────┘
par └────┘ └─┘ └───────────┘
pid ┴ └─┘ └───────────┘
st ────────────────────────────────────────┘└─
3711 cases pairwise_cons.1 H₂ with H₂₁ H₂₂,
id └───────────┘ └┘
src └────┘└───────────┘└─┘ └───────────┘
typ └────┘└───────────┘└─┘└┘└───────────┘
doc └────┘ └─┘ └───────────┘
txt └────┘ └─┘ └───────────┘
par └────┘ └─┘ └───────────┘
pid ┴ └─┘ └───────────┘
st ──────────────────────────────────────┘└─
3712 rintro x (rfl | hx) y (rfl | hy),
src └──────────────────────────────┘
typ └──────────────────────────────┘
doc └──────────────────────────────┘
txt └──────────────────────────────┘
par └──────────────────────────────┘
pid └────────────────────────┘
st ─────────────────────────────────┘└─
3713 exacts [H₁₁, H₂₁ _ hy, H (H₂₁ _ hx), IH H₁₂ H₂₂ _ hx _ hy]
id └─┘ └─┘ └┘ ┴ └─┘ └┘ └┘ └─┘ └─┘ └┘ └┘
src └──────┘ └┘ └─┘ └┘ ┴ └─┘ └─┘ ┴ ┴ └─┘ └─┘ └┘
typ └──────┘└─┘└┘└─┘└─┘└┘└┘┴┴ └─┘└─┘└┘└─┘└┘┴└─┘┴└─┘└─┘└┘└─┘└┘└┘
doc └──────┘ └┘ └─┘ └┘ ┴ └─┘ └─┘ ┴ ┴ └─┘ └─┘ └┘
txt └──────┘ └┘ └─┘ └┘ ┴ └─┘ └─┘ ┴ ┴ └─┘ └─┘ └┘
par └──────┘ └┘ └─┘ └┘ ┴ └─┘ └─┘ ┴ ┴ └─┘ └─┘ └┘
pid └┘ └┘ └─┘ └┘ ┴ └─┘ └─┘ ┴ ┴ └─┘ └─┘ ┴┴
st ────────────────────────────────────────────────────────────┘
3714 end
st └─┘
3715
3716 lemma forall_of_pairwise (H : symmetric R) {l : list α}
id └───────┘ ┴ └──┘ ┴
src └───────┘ └──┘
typ └───────┘ ┴ └──┘ ┴
3717 (hl : pairwise R l) : (∀a∈l, ∀b∈l, a ≠ b → R a b) :=
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ ┴
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘
3718 forall_of_forall_of_pairwise
id └──────────────────────────┘
src └──────────────────────────┘
typ └──────────────────────────┘
3719 (λ a b h hne, H (h hne.symm))
id ┴ ┴ ┴ └─┘ ┴ ┴ └─┘└───┘
src └───┘
typ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘└───┘
3720 (λ _ _ h, (h rfl).elim)
id ┴ ┴ ┴ ┴ └─┘ └──┘
src └─┘ └──┘
typ ┴ ┴ ┴ ┴ └─┘ └──┘
3721 (pairwise.imp (λ _ _ h _, h) hl)
id └──────────┘ ┴ ┴ ┴ ┴ ┴ └┘
src └──────────┘
typ └──────────┘ ┴ ┴ ┴ ┴ ┴ └┘
3722
3723 theorem pairwise_singleton (R) (a : α) : pairwise R [a] :=
id ┴ └──────┘ ┴ ┴┴┴
src └──────┘ ┴ ┴
typ ┴ └──────┘ ┴ ┴┴┴
doc └──────┘
3724 by simp only [pairwise_cons, mem_singleton, forall_prop_of_false (not_mem_nil _), forall_true_iff, pairwise.nil, and_true]
id └───────────┘ └───────────┘ └──────────────────┘ └─────────┘ └─────────────┘ └──────────┘ └──────┘
src └─────────┘└───────────┘└┘└───────────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└┘└──────────┘└┘└──────┘└─
typ └─────────┘└───────────┘└┘└───────────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└┘└──────────┘└┘└──────┘└─
doc └─────────┘ └┘ └┘ ┴ └───┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ ┴ └───┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ ┴ └───┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴ └───┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
3725
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3726 theorem pairwise_pair {a b : α} : pairwise R [a, b] ↔ R a b :=
id ┴ └──────┘ ┴ ┴┴┴ ┴┴ ┴ ┴ ┴ ┴
src └──────┘ ┴ ┴ ┴ ┴
typ ┴ └──────┘ ┴ ┴┴┴ ┴┴ ┴ ┴ ┴ ┴
doc └──────┘
3727 by simp only [pairwise_cons, mem_singleton, forall_eq, forall_prop_of_false (not_mem_nil _), forall_true_iff, pairwise.nil, and_true]
id └───────────┘ └───────────┘ └───────┘ └──────────────────┘ └─────────┘ └─────────────┘ └──────────┘ └──────┘
src └─────────┘└───────────┘└┘└───────────┘└┘└───────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└┘└──────────┘└┘└──────┘└─
typ └─────────┘└───────────┘└┘└───────────┘└┘└───────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└┘└──────────┘└┘└──────┘└─
doc └─────────┘ └┘ └┘ └┘ ┴ └───┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ ┴ └───┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ ┴ └───┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ └───┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
3728
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3729 theorem pairwise_append {l₁ l₂ : list α} : pairwise R (l₁++l₂) ↔
id └──┘ ┴ └──────┘ ┴ └┘└┘└┘ ┴
src └──┘ └──────┘ └┘ ┴
typ └──┘ ┴ └──────┘ ┴ └┘└┘└┘ ┴
doc └──────┘
3730 pairwise R l₁ ∧ pairwise R l₂ ∧ ∀ x ∈ l₁, ∀ y ∈ l₂, R x y :=
id └──────┘ ┴ └┘ ┴ └──────┘ ┴ └┘ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴
src └──────┘ ┴ └──────┘ ┴
typ └──────┘ ┴ └┘ ┴ └──────┘ ┴ └┘ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴
doc └──────┘ └──────┘
3731 by induction l₁ with x l₁ IH; [simp only [list.pairwise.nil, forall_prop_of_false (not_mem_nil _), forall_true_iff, and_true, true_and, nil_append],
id └┘ ┴ └───────────────┘ └──────────────────┘ └─────────┘ └─────────────┘ └──────┘ └──────┘ └────────┘
src └────────┘ └───────────┘ ┴└─────────┘└───────────────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└┘└──────┘└┘└──────┘└┘└────────┘┴
typ └────────┘└┘└───────────┘ ┴└─────────┘└───────────────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└┘└──────┘└┘└──────┘└┘└────────┘┴
doc └────────┘ └───────────┘ └─────────┘ └┘ ┴ └───┘ └┘ └┘ └┘ ┴
txt └────────┘ └───────────┘ └─────────┘ └┘ ┴ └───┘ └┘ └┘ └┘ ┴
par └────────┘ └───────────┘ └─────────┘ └┘ ┴ └───┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──────────┘ ┴└──┘└┘ └┘ ┴ └───┘ └┘ └┘ └┘ ┴
st └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
3732 simp only [cons_append, pairwise_cons, forall_mem_append, IH, forall_mem_cons, forall_and_distrib, and_assoc, and.left_comm]]
id └─────────┘ └───────────┘ └───────────────┘ └┘ └─────────────┘ └────────────────┘ └───────┘ └───────────┘
src └─────────┘└─────────┘└┘└───────────┘└┘└───────────────┘└┘ └┘└─────────────┘└┘└────────────────┘└┘└───────┘└┘└───────────┘┴
typ └─────────┘└─────────┘└┘└───────────┘└┘└───────────────┘└┘└┘└┘└─────────────┘└┘└────────────────┘└┘└───────┘└┘└───────────┘┴
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
st ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
3733
3734 theorem pairwise_append_comm (s : symmetric R) {l₁ l₂ : list α} :
id └───────┘ ┴ └──┘ ┴
src └───────┘ └──┘
typ └───────┘ ┴ └──┘ ┴
3735 pairwise R (l₁++l₂) ↔ pairwise R (l₂++l₁) :=
id └──────┘ ┴ └┘└┘└┘ ┴ └──────┘ ┴ └┘└┘└┘
src └──────┘ └┘ ┴ └──────┘ └┘
typ └──────┘ ┴ └┘└┘└┘ ┴ └──────┘ ┴ └┘└┘└┘
doc └──────┘ └──────┘
3736 have ∀ l₁ l₂ : list α,
id └──┘ ┴
src └──┘
typ └──┘ ┴
3737 (∀ (x : α), x ∈ l₁ → ∀ (y : α), y ∈ l₂ → R x y) →
id ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
3738 (∀ (x : α), x ∈ l₂ → ∀ (y : α), y ∈ l₁ → R x y),
id ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
src ┴ ┴
typ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
3739 from λ l₁ l₂ a x xm y ym, s (a y ym x xm),
id └┘ └┘ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ └┘
typ └┘ └┘ ┴ ┴ └┘ ┴ └┘ ┴ ┴ ┴ └┘ ┴ └┘
3740 by simp only [pairwise_append, and.left_comm]; rw iff.intro (this l₁ l₂) (this l₂ l₁)
id └─────────────┘ └───────────┘ └───────┘ └──┘ └┘ └┘
src └─────────┘└─────────────┘└┘└───────────┘┴ └─┘└───────┘┴ ┴ ┴ └┘ ┴ ┴ └─
typ └─────────┘└─────────────┘└┘└───────────┘┴ └─┘└───────┘┴ ┴ ┴ └┘ └──┘┴└┘┴└┘└─
doc └─────────┘ └┘ ┴ └─┘ ┴ ┴ ┴ └┘ ┴ ┴ └─
txt └─────────┘ └┘ ┴ └─┘ ┴ ┴ ┴ └┘ ┴ ┴ └─
par └─────────┘ └┘ ┴ └─┘ ┴ ┴ ┴ └┘ ┴ ┴ └─
pid ┴└──┘└┘ └┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴└
st └──────────────────────────────────────────────┘└───────┘└──────────────────────────
3741
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3742 theorem pairwise_middle (s : symmetric R) {a : α} {l₁ l₂ : list α} :
id └───────┘ ┴ ┴ └──┘ ┴
src └───────┘ └──┘
typ └───────┘ ┴ ┴ └──┘ ┴
3743 pairwise R (l₁ ++ a::l₂) ↔ pairwise R (a::(l₁++l₂)) :=
id └──────┘ ┴ └┘ └┘ ┴└┘└┘ ┴ └──────┘ ┴ ┴└┘ └┘└┘└┘
src └──────┘ └┘ └┘ ┴ └──────┘ └┘ └┘
typ └──────┘ ┴ └┘ └┘ ┴└┘└┘ ┴ └──────┘ ┴ ┴└┘ └┘└┘└┘
doc └──────┘ └──────┘
3744 show pairwise R (l₁ ++ ([a] ++ l₂)) ↔ pairwise R ([a] ++ l₁ ++ l₂),
id └──────┘ ┴ └┘ └┘ ┴┴┴ └┘ └┘ ┴ └──────┘ ┴ ┴┴┴ └┘ └┘ └┘ └┘
src └──────┘ └┘ ┴ ┴ └┘ ┴ └──────┘ ┴ ┴ └┘ └┘
typ └──────┘ ┴ └┘ └┘ ┴┴┴ └┘ └┘ ┴ └──────┘ ┴ ┴┴┴ └┘ └┘ └┘ └┘
doc └──────┘ └──────┘
3745 by rw [← append_assoc, pairwise_append, @pairwise_append _ _ ([a] ++ l₁), pairwise_append_comm s];
id └──────────┘ └─────────────┘ └─────────────┘ ┴┴┴ └┘ └┘ └──────────────────┘ ┴
src └────┘└──────────┘└┘└─────────────┘└┘ └─────────────┘└───┘ ┴ ┴┴└┘┴ └─┘└──────────────────┘┴ ┴
typ └────┘└──────────┘└┘└─────────────┘└┘ └─────────────┘└───┘ ┴┴┴┴└┘┴└┘└─┘└──────────────────┘┴┴┴
doc └────┘ └┘ └┘ └───┘ ┴ ┴ └─┘ ┴ ┴
txt └────┘ └┘ └┘ └───┘ ┴ ┴ └─┘ ┴ ┴
par └────┘ └┘ └┘ └───┘ ┴ ┴ └─┘ ┴ ┴
pid └──┘ └┘ └┘ └───┘ ┴ ┴ └─┘ ┴ ┴
st └─────────────────┘└───────────────┘└────────────────────────────────┘└──────────────────────┘┴└─
3746 simp only [mem_append, or_comm]
id └────────┘ └─────┘
src └─────────┘└────────┘└┘└─────┘└─
typ └─────────┘└────────┘└┘└─────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st ───────────────────────────────────
3747
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3748 theorem pairwise_map (f : β → α) :
id ┴ ┴
typ ┴ ┴
3749 ∀ {l : list β}, pairwise R (map f l) ↔ pairwise (λ a b : β, R (f a) (f b)) l
id ┴ └──┘ ┴ └──────┘ ┴ └─┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └──────┘ └─┘ ┴ └──────┘
typ ┴ └──┘ ┴ └──────┘ ┴ └─┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘ └──────┘
3750 | [] := by simp only [map, pairwise.nil]
id └┘ └─┘ └──────────┘
src └┘ └─────────┘└─┘└┘└──────────┘└┘
typ └┘ └─────────┘└─┘└┘└──────────┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └─────────────────────────────┘
3751 | (b::l) :=
id ┴└┘┴
src └┘
typ ┴└┘┴
3752 have (∀ a b', b' ∈ l → f b' = a → R (f b) a) ↔ ∀ (b' : β), b' ∈ l → R (f b) (f b'), from
id ┴ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘
src ┴ ┴ ┴ ┴
typ ┴ └┘ └┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └┘
3753 forall_swap.trans $ forall_congr $ λ a, forall_swap.trans $ by simp only [forall_eq'],
id └─────────┘└────┘ └──────────┘ ┴ └─────────┘└────┘ └────────┘
src └─────────┘└────┘ └──────────┘ └─────────┘└────┘ └─────────┘└────────┘┴
typ └─────────┘└────┘ └──────────┘ ┴ └─────────┘└────┘ └─────────┘└────────┘┴
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid ┴└──┘└┘ ┴
st └─────────────────────┘
3754 by simp only [map, pairwise_cons, mem_map, exists_imp_distrib, and_imp, this, pairwise_map]
id └─┘ └───────────┘ └─────┘ └────────────────┘ └─────┘ └──┘
src └─────────┘└─┘└┘└───────────┘└┘└─────┘└┘└────────────────┘└┘└─────┘└┘ └┘ └─
typ └─────────┘└─┘└┘└───────────┘└┘└─────┘└┘└────────────────┘└┘└─────┘└┘└──┘└┘└──────────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────────────────────────────────
3755
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3756 theorem pairwise_of_pairwise_map {S : β → β → Prop} (f : α → β)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
3757 (H : ∀ a b : α, S (f a) (f b) → R a b) {l : list α}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
3758 (p : pairwise S (map f l)) : pairwise R l :=
id └──────┘ ┴ └─┘ ┴ ┴ └──────┘ ┴ ┴
src └──────┘ └─┘ └──────┘
typ └──────┘ ┴ └─┘ ┴ ┴ └──────┘ ┴ ┴
doc └──────┘ └──────┘
3759 ((pairwise_map f).1 p).imp H
id └──────────┘ ┴ ┴ ┴ └─┘ ┴
src └──────────┘ ┴ └─┘
typ └──────────┘ ┴ ┴ ┴ └─┘ ┴
3760
3761 theorem pairwise_map_of_pairwise {S : β → β → Prop} (f : α → β)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
3762 (H : ∀ a b : α, R a b → S (f a) (f b)) {l : list α}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
3763 (p : pairwise R l) : pairwise S (map f l) :=
id └──────┘ ┴ ┴ └──────┘ ┴ └─┘ ┴ ┴
src └──────┘ └──────┘ └─┘
typ └──────┘ ┴ ┴ └──────┘ ┴ └─┘ ┴ ┴
doc └──────┘ └──────┘
3764 (pairwise_map f).2 $ p.imp H
id └──────────┘ ┴ ┴ ┴└──┘ ┴
src └──────────┘ ┴ └──┘
typ └──────────┘ ┴ ┴ ┴└──┘ ┴
3765
3766 theorem pairwise_filter_map (f : β → option α) {l : list β} :
id ┴ └────┘ ┴ └──┘ ┴
src └────┘ └──┘
typ ┴ └────┘ ┴ └──┘ ┴
3767 pairwise R (filter_map f l) ↔ pairwise (λ a a' : β, ∀ (b ∈ f a) (b' ∈ f a'), R b b') l :=
id └──────┘ ┴ └────────┘ ┴ ┴ ┴ └──────┘ ┴ ┴┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘ ┴
src └──────┘ └────────┘ ┴ └──────┘
typ └──────┘ ┴ └────────┘ ┴ ┴ ┴ └──────┘ ┴ ┴┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘ ┴
doc └──────┘ └──────┘
3768 let S (a a' : β) := ∀ (b ∈ f a) (b' ∈ f a'), R b b' in
id ┴ ┴ ┴┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
typ ┴ ┴ ┴┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘
3769 begin
st └─────
3770 simp only [option.mem_def], induction l with a l IH,
id └────────────┘ ┴
src └─────────┘└────────────┘┴ └────────┘ └──────────┘
typ └─────────┘└────────────┘┴ └────────┘┴└──────────┘
doc └─────────┘ ┴ └────────┘ └──────────┘
txt └─────────┘ ┴ └────────┘ └──────────┘
par └─────────┘ ┴ └────────┘ └──────────┘
pid ┴└──┘└┘ ┴ ┴ ┴└─────────┘
st ───────────────────────────┘└───────────────────────┘└─
3771 { simp only [filter_map, pairwise.nil] },
id └────────┘ └──────────┘
src └─────────┘└────────┘└┘└──────────┘└┘
typ └─────────┘└────────┘└┘└──────────┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st ───┘└───────────────────────────────────┘└┘└
3772 cases e : f a with b,
id ┴ ┴
src └────┘ └─┘ ┴ └─────┘
typ └────┘ └─┘┴┴┴└─────┘
doc └────┘ └─┘ ┴ └─────┘
txt └────┘ └─┘ ┴ └─────┘
par └────┘ └─┘ ┴ └─────┘
pid ┴ └─┘ ┴ └─────┘
st ─────────────────────┘└─
3773 { rw [filter_map_cons_none _ _ e, IH, pairwise_cons],
id └──────────────────┘ ┴ └┘ └───────────┘
src └──┘└──────────────────┘└───┘ └┘ └┘└───────────┘┴
typ └──┘└──────────────────┘└───┘┴└┘└┘└┘└───────────┘┴
doc └──┘ └───┘ └┘ └┘ ┴
txt └──┘ └───┘ └┘ └┘ ┴
par └──┘ └───┘ └┘ └┘ ┴
pid └┘ └───┘ └┘ └┘ ┴
st ───┘└────────────────────────────┘└──┘└─────────────┘┴└─
3774 simp only [e, forall_prop_of_false not_false, forall_3_true_iff, true_and] },
id ┴ └──────────────────┘ └───────┘ └───────────────┘ └──────┘
src └─────────┘ └┘└──────────────────┘┴└───────┘└┘└───────────────┘└┘└──────┘└┘
typ └─────────┘┴└┘└──────────────────┘┴└───────┘└┘└───────────────┘└┘└──────┘└┘
doc └─────────┘ └┘ ┴ └┘ └┘ └┘
txt └─────────┘ └┘ ┴ └┘ └┘ └┘
par └─────────┘ └┘ ┴ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴ └┘ └┘ ┴┴
st ──────────────────────────────────────────────────────────────────────────────┘└┘└
3775 rw [filter_map_cons_some _ _ _ e],
id └──────────────────┘ ┴
src └──┘└──────────────────┘└─────┘ ┴
typ └──┘└──────────────────┘└─────┘┴┴
doc └──┘ └─────┘ ┴
txt └──┘ └─────┘ ┴
par └──┘ └─────┘ ┴
pid └┘ └─────┘ ┴
st ─────────────────────────────────┘┴└─
3776 simp only [pairwise_cons, mem_filter_map, exists_imp_distrib, and_imp, IH, e, forall_eq'],
id └───────────┘ └────────────┘ └────────────────┘ └─────┘ └┘ ┴ └────────┘
src └─────────┘└───────────┘└┘└────────────┘└┘└────────────────┘└┘└─────┘└┘ └┘ └┘└────────┘┴
typ └─────────┘└───────────┘└┘└────────────┘└┘└────────────────┘└┘└─────┘└┘└┘└┘┴└┘└────────┘┴
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
st ──────────────────────────────────────────────────────────────────────────────────────────┘└─
3777 show (∀ (a' : α) (x : β), x ∈ l → f x = some a' → R b a') ∧ pairwise S l ↔
id ┴ ┴
src └───┘ └─────┘ └─────┘ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
typ └───┘ └─────┘ └─────┘ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
doc └───┘ └─────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
txt └───┘ └─────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
par └───┘ └─────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
pid └───┘ └─────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └
st ─────────────────────────────────────────────────────────────────────────────
3778 (∀ (a' : β), a' ∈ l → ∀ (b' : α), f a' = some b' → R b b') ∧ pairwise S l,
id ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └──────┘ ┴ ┴
src ───────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴└──┘┴ ┴ ┴ ┴ ┴ └┘ ┴└──────┘┴ ┴
typ ───────┘ └─────┘┴┴ ┴ ┴ ┴ ┴ ┴ └─────┘┴┴ ┴┴┴ ┴┴┴└──┘┴ ┴ ┴┴┴┴┴ └┘ ┴└──────┘┴┴┴┴
doc ───────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴└──────┘┴ ┴
txt ───────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴
par ───────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴
pid ───────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴
st ────────────────────────────────────────────────────────────────────────────────┘└─
3779 from and_congr ⟨λ h b mb a ma, h a b mb ma, λ h a b mb ma, h b mb a ma⟩ iff.rfl
id └───────┘ └─────┘
src └───┘└───────┘┴ └────────────┘ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ └┘└─────┘┴
typ └───┘└───────┘┴ └────────────┘ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ └┘└─────┘┴
doc └───┘ ┴ └────────────┘ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ └┘ ┴
txt └───┘ ┴ └────────────┘ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ └┘ ┴
par └───┘ ┴ └────────────┘ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ └┘ ┴
pid └───┘ ┴ └────────────┘ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ └┘ ┴
st ─────────────────────────────────────────────────────────────────────────────────┘
3780 end
st └─┘
3781
3782 theorem pairwise_filter_map_of_pairwise {S : β → β → Prop} (f : α → option β)
id ┴ ┴ ┴ └────┘ ┴
src └────┘
typ ┴ ┴ ┴ └────┘ ┴
3783 (H : ∀ (a a' : α), R a a' → ∀ (b ∈ f a) (b' ∈ f a'), S b b') {l : list α}
id ┴ ┴ ┴ └┘ ┴┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ └┘ ┴┴ ┴ ┴ └┘ ┴ └┘ ┴ ┴ └┘ └──┘ ┴
3784 (p : pairwise R l) : pairwise S (filter_map f l) :=
id └──────┘ ┴ ┴ └──────┘ ┴ └────────┘ ┴ ┴
src └──────┘ └──────┘ └────────┘
typ └──────┘ ┴ ┴ └──────┘ ┴ └────────┘ ┴ ┴
doc └──────┘ └──────┘
3785 (pairwise_filter_map _).2 $ p.imp H
id └─────────────────┘ ┴ ┴└──┘ ┴
src └─────────────────┘ ┴ └──┘
typ └─────────────────┘ ┴ ┴└──┘ ┴
3786
3787 theorem pairwise_filter (p : α → Prop) [decidable_pred p] {l : list α} :
id ┴ └────────────┘ ┴ └──┘ ┴
src └────────────┘ └──┘
typ ┴ └────────────┘ ┴ └──┘ ┴
3788 pairwise R (filter p l) ↔ pairwise (λ x y, p x → p y → R x y) l :=
id └──────┘ ┴ └────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ └────┘ ┴ └──────┘
typ └──────┘ ┴ └────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘ └──────┘
3789 begin
st └─────
3790 rw [← filter_map_eq_filter, pairwise_filter_map],
id └──────────────────┘ └─────────────────┘
src └────┘└──────────────────┘└┘└─────────────────┘┴
typ └────┘└──────────────────┘└┘└─────────────────┘┴
doc └────┘ └┘ ┴
txt └────┘ └┘ ┴
par └────┘ └┘ ┴
pid └──┘ └┘ ┴
st ───────────────────────────┘└───────────────────┘└──
3791 apply pairwise.iff, intros, simp only [option.mem_def, option.guard_eq_some, and_imp, forall_eq'],
id └──────────┘ └────────────┘ └──────────────────┘ └─────┘ └────────┘
src └────┘└──────────┘ └────┘ └─────────┘└────────────┘└┘└──────────────────┘└┘└─────┘└┘└────────┘┴
typ └────┘└──────────┘ └────┘ └─────────┘└────────────┘└┘└──────────────────┘└┘└─────┘└┘└────────┘┴
doc └────┘ └────┘ └─────────┘ └┘ └┘ └┘ ┴
txt └────┘ └────┘ └─────────┘ └┘ └┘ └┘ ┴
par └────┘ └────┘ └─────────┘ └┘ └┘ └┘ ┴
pid ┴ ┴└──┘└┘ └┘ └┘ └┘ ┴
st ───────────────────┘└──────┘└─────────────────────────────────────────────────────────────────────┘└─
3792 end
st ──┘
3793
3794 theorem pairwise_filter_of_pairwise (p : α → Prop) [decidable_pred p] {l : list α}
id ┴ └────────────┘ ┴ └──┘ ┴
src └────────────┘ └──┘
typ ┴ └────────────┘ ┴ └──┘ ┴
3795 : pairwise R l → pairwise R (filter p l) :=
id └──────┘ ┴ ┴ └──────┘ ┴ └────┘ ┴ ┴
src └──────┘ └──────┘ └────┘
typ └──────┘ ┴ ┴ └──────┘ ┴ └────┘ ┴ ┴
doc └──────┘ └──────┘
3796 pairwise_of_sublist (filter_sublist _)
id └─────────────────┘ └────────────┘
src └─────────────────┘ └────────────┘
typ └─────────────────┘ └────────────┘
3797
3798 theorem pairwise_join {L : list (list α)} : pairwise R (join L) ↔
id └──┘ └──┘ ┴ └──────┘ ┴ └──┘ ┴ ┴
src └──┘ └──┘ └──────┘ └──┘ ┴
typ └──┘ └──┘ ┴ └──────┘ ┴ └──┘ ┴ ┴
doc └──────┘
3799 (∀ l ∈ L, pairwise R l) ∧ pairwise (λ l₁ l₂, ∀ (x ∈ l₁) (y ∈ l₂), R x y) L :=
id ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ └┘ └┘ ┴┴ └┘ ┴ └┘ ┴ ┴ ┴ ┴
src └──────┘ ┴ └──────┘
typ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ └┘ └┘ ┴┴ └┘ ┴ └┘ ┴ ┴ ┴ ┴
doc └──────┘ └──────┘
3800 begin
st └─────
3801 induction L with l L IH, {simp only [join, pairwise.nil, forall_prop_of_false (not_mem_nil _), forall_const, and_self]},
id ┴ └──┘ └──────────┘ └──────────────────┘ └─────────┘ └──────────┘ └──────┘
src └────────┘ └──────────┘ └─────────┘└──┘└┘└──────────┘└┘└──────────────────┘┴ └─────────┘└───┘└──────────┘└┘└──────┘┴
typ └────────┘┴└──────────┘ └─────────┘└──┘└┘└──────────┘└┘└──────────────────┘┴ └─────────┘└───┘└──────────┘└┘└──────┘┴
doc └────────┘ └──────────┘ └─────────┘ └┘ └┘ ┴ └───┘ └┘ ┴
txt └────────┘ └──────────┘ └─────────┘ └┘ └┘ ┴ └───┘ └┘ ┴
par └────────┘ └──────────┘ └─────────┘ └┘ └┘ ┴ └───┘ └┘ ┴
pid ┴ ┴└─────────┘ ┴└──┘└┘ └┘ └┘ ┴ └───┘ └┘ ┴
st ────────────────────────┘└─────────────────────────────────────────────────────────────────────────────────────────────┘└┘└
3802 have : (∀ (x : α), x ∈ l → ∀ (y : α) (x_1 : list α), x_1 ∈ L → y ∈ x_1 → R x y) ↔
id ┴ └──┘ ┴ ┴
src └─────┘ └────┘ ┴ ┴ ┴┴┴ ┴ ┴ └────┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
typ └─────┘ └────┘ ┴ ┴ ┴┴┴ ┴ ┴ └────┘ └───────┘└──┘┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴ └┘ └
doc └─────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
txt └─────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
par └─────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
pid └───┘└┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
st ────────────────────────────────────────────────────────────────────────────────────
3803 ∀ (a' : list α), a' ∈ L → ∀ (x : α), x ∈ l → ∀ (y : α), y ∈ a' → R x y :=
id └──┘ ┴ ┴ ┴ ┴ ┴
src ─────────┘ └─────┘└──┘┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
typ ─────────┘ └─────┘└──┘┴ ┴ ┴ ┴ ┴┴┴ ┴ └────┘ ┴ ┴ ┴ ┴┴┴ ┴ └────┘┴┴ ┴ ┴┴┴ ┴ ┴┴┴ ┴ └───
doc ─────────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
txt ─────────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
par ─────────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
pid ─────────┘ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
st ────────────────────────────────────────────────────────────────────────────────────
3804 ⟨λ h a b c d e, h c d e a b, λ h c d e a b, h a b c d e⟩,
src ───┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
typ ───┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc ───┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
txt ───┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
par ───┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
pid ───┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ └┘ └────────────┘ ┴ ┴ ┴ ┴ ┴ ┴
st ───────────────────────────────────────────────────────────┘└─
3805 simp only [join, pairwise_append, IH, mem_join, exists_imp_distrib, and_imp, this, forall_mem_cons, pairwise_cons],
id └──┘ └─────────────┘ └┘ └──────┘ └────────────────┘ └─────┘ └──┘ └─────────────┘ └───────────┘
src └─────────┘└──┘└┘└─────────────┘└┘ └┘└──────┘└┘└────────────────┘└┘└─────┘└┘ └┘└─────────────┘└┘└───────────┘┴
typ └─────────┘└──┘└┘└─────────────┘└┘└┘└┘└──────┘└┘└────────────────┘└┘└─────┘└┘└──┘└┘└─────────────┘└┘└───────────┘┴
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
st ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘└─
3806 simp only [and_assoc, and_comm, and.left_comm],
id └───────┘ └──────┘ └───────────┘
src └─────────┘└───────┘└┘└──────┘└┘└───────────┘┴
typ └─────────┘└───────┘└┘└──────┘└┘└───────────┘┴
doc └─────────┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ ┴
st ───────────────────────────────────────────────┘└─
3807 end
st ──┘
3808
3809 @[simp] theorem pairwise_reverse : ∀ {R} {l : list α},
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
3810 pairwise R (reverse l) ↔ pairwise (λ x y, R y x) l :=
id └──────┘ ┴ └─────┘ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──────┘ └─────┘ ┴ └──────┘
typ └──────┘ ┴ └─────┘ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──────┘ └──────┘
3811 suffices ∀ {R l}, @pairwise α R l → pairwise (λ x y, R y x) (reverse l),
id ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
src └──────┘ └──────┘ └─────┘
typ ┴ ┴ └──────┘ ┴ ┴ ┴ └──────┘ ┴ ┴ ┴ ┴ ┴ └─────┘ ┴
doc └──────┘ └──────┘
3812 from λ R l, ⟨λ p, reverse_reverse l ▸ this p, this⟩,
id ┴ ┴ ┴ └─────────────┘ ┴ ┴ └──┘ ┴ └──┘
src └─────────────┘ ┴
typ ┴ ┴ ┴ └─────────────┘ ┴ ┴ └──┘ ┴ └──┘
3813 λ R l p, by induction p with a l h p IH;
id ┴ ┴ ┴ ┴
src └────────┘ └──────────────┘
typ ┴ ┴ ┴ └────────┘┴└──────────────┘
doc └────────┘ └──────────────┘
txt └────────┘ └──────────────┘
par └────────┘ └──────────────┘
pid ┴ ┴└─────────────┘
st └─────────────────────────────
3814 [apply pairwise.nil, simpa only [reverse_cons, pairwise_append, IH,
id ┴ └──────────┘ └──────────┘ └─────────────┘ └┘
src ┴└────┘└──────────┘ └──────────┘└──────────┘└┘└─────────────┘└┘ └─
typ ┴└────┘└──────────┘ └──────────┘└──────────┘└┘└─────────────┘└┘└┘└─
doc └────┘ └──────────┘ └┘ └┘ └─
txt └────┘ └──────────┘ └┘ └┘ └─
par └────┘ └──────────┘ └┘ └┘ └─
pid ┴ ┴└──┘└┘ └┘ └┘ └─
st ──────────────────────────────────────────────────────────────────────
3815 pairwise_cons, forall_prop_of_false (not_mem_nil _), forall_true_iff,
id └───────────┘ └──────────────────┘ └─────────┘ └─────────────┘
src ───┘└───────────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└─
typ ───┘└───────────┘└┘└──────────────────┘┴ └─────────┘└───┘└─────────────┘└─
doc ───┘ └┘ ┴ └───┘ └─
txt ───┘ └┘ ┴ └───┘ └─
par ───┘ └┘ ┴ └───┘ └─
pid ───┘ └┘ ┴ └───┘ └─
st ──────────────────────────────────────────────────────────────────────────
3816 pairwise.nil, mem_reverse, mem_singleton, forall_eq, true_and] using h]
id └──────────┘ └─────────┘ └───────────┘ └───────┘ └──────┘ ┴
src ───┘└──────────┘└┘└─────────┘└┘└───────────┘└┘└───────┘└┘└──────┘└──────┘
typ ───┘└──────────┘└┘└─────────┘└┘└───────────┘└┘└───────┘└┘└──────┘└──────┘┴
doc ───┘ └┘ └┘ └┘ └┘ └──────┘
txt ───┘ └┘ └┘ └┘ └┘ └──────┘
par ───┘ └┘ └┘ └┘ └┘ └──────┘
pid ───┘ └┘ └┘ └┘ └┘ ┴┴└────┘
st ──────────────────────────────────────────────────────────────────────────┘
3817
3818 theorem pairwise_iff_nth_le {R} : ∀ {l : list α},
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3819 pairwise R l ↔ ∀ i j (h₁ : j < length l) (h₂ : i < j), R (nth_le l i (lt_trans h₂ h₁)) (nth_le l j h₁)
id └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └──────┘ └┘ └┘ └────┘ ┴ ┴ └┘
src └──────┘ ┴ ┴ └────┘ ┴ └────┘ └──────┘ └────┘
typ └──────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └──────┘ └┘ └┘ └────┘ ┴ ┴ └┘
doc └──────┘
3820 | [] := by simp only [pairwise.nil, true_iff]; exact λ i j h, (not_lt_zero j).elim h
id └┘ └──────────┘ └──────┘ └─────────┘
src └┘ └─────────┘└──────────┘└┘└──────┘┴ └────┘ └──────┘ └─────────┘┴ └─────┘ ┴
typ └┘ └─────────┘└──────────┘└┘└──────┘┴ └────┘ └──────┘ └─────────┘┴ └─────┘ ┴
doc └─────────┘ └┘ ┴ └────┘ └──────┘ ┴ └─────┘ ┴
txt └─────────┘ └┘ ┴ └────┘ └──────┘ ┴ └─────┘ ┴
par └─────────┘ └┘ ┴ └────┘ └──────┘ ┴ └─────┘ ┴
pid ┴└──┘└┘ └┘ ┴ ┴ └──────┘ ┴ └─────┘ ┴
st └─────────────────────────────────────────────────────────────────────────┘
3821 | (a::l) := begin
id └┘
src └┘
typ └┘
st └─────
3822 rw [pairwise_cons, pairwise_iff_nth_le],
id └───────────┘
src └──┘└───────────┘└┘ ┴
typ └──┘└───────────┘└┘└─────────────────┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ──────────────────┘└───────────────────┘└──
3823 refine ⟨λ H i j h₁ h₂, _, λ H, ⟨λ a' m, _,
src └─────┘ └───────────────┘ └──┘ └─────────
typ └─────┘ └───────────────┘ └──┘ └─────────
doc └─────┘ └───────────────┘ └──┘ └─────────
txt └─────┘ └───────────────┘ └──┘ └─────────
par └─────┘ └───────────────┘ └──┘ └─────────
pid ┴ └───────────────┘ └──┘ └─────────
st ─────────────────────────────────────────────
3824 λ i j h₁ h₂, H _ _ (succ_lt_succ h₁) (succ_lt_succ h₂)⟩⟩,
id └──────────┘
src ───┘ └──────────┘ └───┘ ┴ └┘ └──────────┘┴ └─┘
typ ───┘ └──────────┘ └───┘ ┴ └┘ └──────────┘┴ └─┘
doc ───┘ └──────────┘ └───┘ ┴ └┘ ┴ └─┘
txt ───┘ └──────────┘ └───┘ ┴ └┘ ┴ └─┘
par ───┘ └──────────┘ └───┘ ┴ └┘ ┴ └─┘
pid ───┘ └──────────┘ └───┘ ┴ └┘ ┴ └─┘
st ───────────────────────────────────────────────────────────┘└─
3825 { cases j with j, {exact (not_lt_zero _).elim h₂},
id ┴ └─────────┘ └┘
src └────┘ └─────┘ └────┘ └─────────┘└───────┘
typ └────┘┴└─────┘ └────┘ └─────────┘└───────┘└┘
doc └────┘ └─────┘ └────┘ └───────┘
txt └────┘ └─────┘ └────┘ └───────┘
par └────┘ └─────┘ └────┘ └───────┘
pid ┴ └─────┘ ┴ └───────┘
st ───┘└────────────┘└──────────────────────────────┘└┘└
3826 cases i with i,
id ┴
src └────┘ └─────┘
typ └────┘┴└─────┘
doc └────┘ └─────┘
txt └────┘ └─────┘
par └────┘ └─────┘
pid ┴ └─────┘
st ─────────────────┘└─
3827 { exact H.1 _ (nth_le_mem l _ _) },
id ┴ └────────┘ ┴
src └────┘ └───┘ └────────┘┴ └────┘
typ └────┘┴└───┘ └────────┘┴┴└────┘
doc └────┘ └───┘ ┴ └────┘
txt └────┘ └───┘ ┴ └────┘
par └────┘ └───┘ ┴ └────┘
pid ┴ └───┘ ┴ └───┘┴
st ─────┘└─────────────────────────────┘└┘└
3828 { exact H.2 _ _ (lt_of_succ_lt_succ h₁) (lt_of_succ_lt_succ h₂) } },
id ┴ └┘ └────────────────┘ └┘
src └────┘ └─────┘ ┴ └┘ └────────────────┘┴ └┘
typ └────┘┴└─────┘ ┴└┘└┘ └────────────────┘┴└┘└┘
doc └────┘ └─────┘ ┴ └┘ ┴ └┘
txt └────┘ └─────┘ ┴ └┘ ┴ └┘
par └────┘ └─────┘ ┴ └┘ ┴ └┘
pid ┴ └─────┘ ┴ └┘ ┴ ┴┴
st ───────────────────────────────────────────────────────────────────┘└──┘└
3829 { rcases nth_le_of_mem m with ⟨n, h, rfl⟩,
id └───────────┘ ┴
src └─────┘└───────────┘┴ └───────────────┘
typ └─────┘└───────────┘┴┴└───────────────┘
doc └─────┘ ┴ └───────────────┘
txt └─────┘ ┴ └───────────────┘
par └─────┘ ┴ └───────────────┘
pid ┴ ┴ └───────────────┘
st ──────────────────────────────────────────┘└─
3830 exact H _ _ (succ_lt_succ h) (succ_pos _) }
id ┴ └──────────┘ ┴ └──────┘
src └────┘ └───┘ └──────────┘┴ └┘ └──────┘└──┘
typ └────┘┴└───┘ └──────────┘┴┴└┘ └──────┘└──┘
doc └────┘ └───┘ ┴ └┘ └──┘
txt └────┘ └───┘ ┴ └┘ └──┘
par └────┘ └───┘ ┴ └┘ └──┘
pid ┴ └───┘ ┴ └┘ └─┘┴
st ─────────────────────────────────────────────┘└─
3831 end
st ──┘
3832
3833 theorem pairwise_sublists' {R} : ∀ {l : list α}, pairwise R l →
id ┴ └──┘ ┴ └──────┘ ┴ ┴
src └──┘ └──────┘
typ ┴ └──┘ ┴ └──────┘ ┴ ┴
doc └──────┘
3834 pairwise (lex (swap R)) (sublists' l)
id └──────┘ └─┘ └──┘ ┴ └───────┘ ┴
src └──────┘ └─┘ └──┘ └───────┘
typ └──────┘ └─┘ └──┘ ┴ └───────┘ ┴
doc └──────┘ └───────┘
3835 | _ pairwise.nil := pairwise_singleton _ _
id └──────────┘ └────────────────┘
src └──────────┘ └────────────────┘
typ └──────────┘ └────────────────┘
3836 | _ (@pairwise.cons _ _ a l H₁ H₂) :=
id └───────────┘
src └───────────┘
typ └───────────┘
3837 begin
st └─────
3838 simp only [sublists'_cons, pairwise_append, pairwise_map, mem_sublists', mem_map, exists_imp_distrib, and_imp],
id └────────────┘ └─────────────┘ └──────────┘ └───────────┘ └─────┘ └────────────────┘ └─────┘
src └─────────┘└────────────┘└┘└─────────────┘└┘└──────────┘└┘└───────────┘└┘└─────┘└┘└────────────────┘└┘└─────┘┴
typ └─────────┘└────────────┘└┘└─────────────┘└┘└──────────┘└┘└───────────┘└┘└─────┘└┘└────────────────┘└┘└─────┘┴
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
st ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘└─
3839 have IH := pairwise_sublists' H₂,
id └────────────────┘ └┘
src └─────────┘ ┴
typ └─────────┘└────────────────┘┴└┘
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid └─────┘┴└─┘ ┴
st ───────────────────────────────────┘└─
3840 refine ⟨IH, IH.imp (λ l₁ l₂, lex.cons), _⟩,
id └────┘ └──────┘
src └─────┘ └┘└────┘┴ └──────┘└──────┘└───┘
typ └─────┘ └┘└────┘┴ └──────┘└──────┘└───┘
doc └─────┘ └┘ ┴ └──────┘ └───┘
txt └─────┘ └┘ ┴ └──────┘ └───┘
par └─────┘ └┘ ┴ └──────┘ └───┘
pid ┴ └┘ ┴ └──────┘ └───┘
st ─────────────────────────────────────────────┘└─
3841 intros l₁ sl₁ x l₂ sl₂ e, subst e,
id ┴
src └──────────────────────┘ └────┘
typ └──────────────────────┘ └────┘┴
doc └──────────────────────┘ └────┘
txt └──────────────────────┘ └────┘
par └──────────────────────┘ └────┘
pid └────────────────┘ ┴
st ───────────────────────────┘└───────┘└─
3842 cases l₁ with b l₁, {constructor},
id └┘
src └────┘ └────────┘ └─────────┘
typ └────┘└┘└────────┘ └─────────┘
doc └────┘ └────────┘ └─────────┘
txt └────┘ └────────┘ └─────────┘
par └────┘ └────────┘ └─────────┘
pid ┴ └────────┘
st ─────────────────────┘└────────────┘└┘└
3843 exact lex.rel (H₁ _ $ subset_of_sublist sl₁ $ mem_cons_self _ _)
id └─────┘ └┘ └───────────────┘ └─┘ └───────────┘
src └────┘└─────┘┴ └─┘ ┴└───────────────┘┴ ┴ ┴└───────────┘└─────
typ └────┘└─────┘┴ └┘└─┘ ┴└───────────────┘┴└─┘┴ ┴└───────────┘└─────
doc └────┘ ┴ └─┘ ┴ ┴ ┴ ┴ └─────
txt └────┘ ┴ └─┘ ┴ ┴ ┴ ┴ └─────
par └────┘ ┴ └─┘ ┴ ┴ ┴ ┴ └─────
pid ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └───┘└
st ─────────────────────────────────────────────────────────────────────
3844 end
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
3845
3846 theorem pairwise_sublists {R} {l : list α} (H : pairwise R l) :
id └──┘ ┴ └──────┘ ┴ ┴
src └──┘ └──────┘
typ └──┘ ┴ └──────┘ ┴ ┴
doc └──────┘
3847 pairwise (λ l₁ l₂, lex R (reverse l₁) (reverse l₂)) (sublists l) :=
id └──────┘ └┘ └┘ └─┘ ┴ └─────┘ └┘ └─────┘ └┘ └──────┘ ┴
src └──────┘ └─┘ └─────┘ └─────┘ └──────┘
typ └──────┘ └┘ └┘ └─┘ ┴ └─────┘ └┘ └─────┘ └┘ └──────┘ ┴
doc └──────┘ └──────┘
3848 by have := pairwise_sublists' (pairwise_reverse.2 H);
id └────────────────┘ └──────────────┘ ┴
src └──────┘└────────────────┘┴ └──────────────┘└─┘ ┴
typ └──────┘└────────────────┘┴ └──────────────┘└─┘┴┴
doc └──────┘ ┴ └─┘ ┴
txt └──────┘ ┴ └─┘ ┴
par └──────┘ ┴ └─┘ ┴
pid └───┘└─┘ ┴ └─┘ ┴
st └───────────────────────────────────────────────────
3849 rwa [sublists'_reverse, pairwise_map] at this
id └───────────────┘ └──────────┘
src └───┘└───────────────┘└┘└──────────┘└─────────
typ └───┘└───────────────┘└┘└──────────┘└─────────
doc └───┘ └┘ └─────────
txt └───┘ └┘ └─────────
par └───┘ └┘ └─────────
pid └┘ └┘ ┴└──────┘└
st ───────┘└───────────────┘└────────────┘┴└────────
3850
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
3851 /- pairwise reduct -/
src ──────────────────────
typ ──────────────────────
doc ──────────────────────
txt ──────────────────────
par ──────────────────────
pid ──────────────────────
st ──────────────────────
3852
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3853 variable [decidable_rel R]
id └───────────┘
src └───────────┘
typ └───────────┘
3854
3855 @[simp] theorem pw_filter_nil : pw_filter R [] = [] := rfl
id └───────┘ ┴ └┘ ┴ └┘ └─┘
src └───────┘ └┘ ┴ └┘ └─┘
typ └───────┘ ┴ └┘ ┴ └┘ └─┘
doc └──┘ └───────┘
3856
3857 @[simp] theorem pw_filter_cons_of_pos {a : α} {l : list α} (h : ∀ b ∈ pw_filter R l, R a b) :
id ┴ └──┘ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ └───────┘
typ ┴ └──┘ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └───────┘
3858 pw_filter R (a::l) = a :: pw_filter R l := if_pos h
id └───────┘ ┴ ┴└┘┴ ┴ ┴ └┘ └───────┘ ┴ ┴ └────┘ ┴
src └───────┘ └┘ ┴ └┘ └───────┘ └────┘
typ └───────┘ ┴ ┴└┘┴ ┴ ┴ └┘ └───────┘ ┴ ┴ └────┘ ┴
doc └───────┘ └───────┘
3859
3860 @[simp] theorem pw_filter_cons_of_neg {a : α} {l : list α} (h : ¬ ∀ b ∈ pw_filter R l, R a b) :
id ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └───────┘
typ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └───────┘
3861 pw_filter R (a::l) = pw_filter R l := if_neg h
id └───────┘ ┴ ┴└┘┴ ┴ └───────┘ ┴ ┴ └────┘ ┴
src └───────┘ └┘ ┴ └───────┘ └────┘
typ └───────┘ ┴ ┴└┘┴ ┴ └───────┘ ┴ ┴ └────┘ ┴
doc └───────┘ └───────┘
3862
3863 theorem pw_filter_map (f : β → α) : Π (l : list β), pw_filter R (map f l) = map f (pw_filter (λ x y, R (f x) (f y)) l)
id ┴ ┴ ┴ └──┘ ┴ └───────┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └───────┘ └─┘ ┴ └─┘ └───────┘
typ ┴ ┴ ┴ └──┘ ┴ └───────┘ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └───────┘ └───────┘
3864 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
3865 | (x :: xs) :=
id ┴ └┘ └┘
src └┘
typ ┴ └┘ └┘
3866 if h : ∀ b ∈ pw_filter R (map f xs), R (f x) b
id └┘ ┴ └───────┘ ┴ └─┘ ┴ ┴ ┴ ┴
src └┘ └───────┘ └─┘
typ └┘ ┴ └───────┘ ┴ └─┘ ┴ ┴ ┴ ┴
doc └───────┘
3867 then have h' : ∀ (b : β), b ∈ pw_filter (λ (x y : β), R (f x) (f y)) xs → R (f x) (f b),
id ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └───────┘
typ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └───────┘
3868 from λ b hb, h _ (by rw [pw_filter_map]; apply mem_map_of_mem _ hb),
id ┴ └┘ ┴ └───────────┘ └────────────┘ └┘
src └──┘ ┴ └────┘└────────────┘└─┘
typ ┴ └┘ ┴ └──┘└───────────┘┴ └────┘└────────────┘└─┘└┘
doc └──┘ ┴ └────┘ └─┘
txt └──┘ ┴ └────┘ └─┘
par └──┘ ┴ └────┘ └─┘
pid └┘ ┴ ┴ └─┘
st └────────────────┘┴└─────────────────────────┘
3869 by rw [map,pw_filter_cons_of_pos h,pw_filter_cons_of_pos h',pw_filter_map,map]
id └─┘ └───────────────────┘ ┴ └───────────────────┘ └┘ └───────────┘ └─┘
src └──┘└─┘┴└───────────────────┘┴ ┴└───────────────────┘┴ ┴ ┴└─┘└─
typ └──┘└─┘┴└───────────────────┘┴┴┴└───────────────────┘┴└┘┴└───────────┘┴└─┘└─
doc └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └─
txt └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └─
par └──┘ ┴ ┴ ┴ ┴ ┴ ┴ └─
pid └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└
st └──────┘└──────────────────────┘└───────────────────────┘└────────────┘└──┘┴└
3870 else have h' : ¬∀ (b : β), b ∈ pw_filter (λ (x y : β), R (f x) (f y)) xs → R (f x) (f b),
id └──┘ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ───┘ ┴ ┴ └───────┘
typ ───┘ └──┘ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc ───┘ └───────┘
txt ───┘
par ───┘
pid ───┘
st ───┘
3871 from λ hh, h $ λ a ha,
id └┘ ┴ ┴ └┘
typ └┘ ┴ ┴ └┘
3872 by { rw [pw_filter_map,mem_map] at ha, rcases ha with ⟨b,hb₀,hb₁⟩,
id └───────────┘ └─────┘ └┘
src └──┘ ┴└─────┘└─────┘ └─────┘ └───────────────┘
typ └──┘└───────────┘┴└─────┘└─────┘ └─────┘└┘└───────────────┘
doc └──┘ ┴ └─────┘ └─────┘ └───────────────┘
txt └──┘ ┴ └─────┘ └─────┘ └───────────────┘
par └──┘ ┴ └─────┘ └─────┘ └───────────────┘
pid └┘ ┴ ┴└────┘ ┴ └───────────────┘
st └──────────────────┘└──────┘┴└────┘└──────────────────────────┘└─
3873 subst a, exact hh _ hb₀, },
id ┴ └┘ └─┘
src └────┘ └────┘ └─┘
typ └────┘┴ └────┘└┘└─┘└─┘
doc └────┘ └────┘ └─┘
txt └────┘ └────┘ └─┘
par └────┘ └────┘ └─┘
pid ┴ ┴ └─┘
st ──────────────────────┘└──────────────┘└──┘
3874 by rw [map,pw_filter_cons_of_neg h,pw_filter_cons_of_neg h',pw_filter_map]
id └─┘ └───────────────────┘ ┴ └───────────────────┘ └┘ └───────────┘
src └──┘└─┘┴└───────────────────┘┴ ┴└───────────────────┘┴ ┴ └─
typ └──┘└─┘┴└───────────────────┘┴┴┴└───────────────────┘┴└┘┴└───────────┘└─
doc └──┘ ┴ ┴ ┴ ┴ ┴ └─
txt └──┘ ┴ ┴ ┴ ┴ ┴ └─
par └──┘ ┴ ┴ ┴ ┴ ┴ └─
pid └┘ ┴ ┴ ┴ ┴ ┴ ┴└
st └──────┘└──────────────────────┘└───────────────────────┘└────────────┘┴└
3875
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3876 theorem pw_filter_sublist : ∀ (l : list α), pw_filter R l <+ l
id ┴ └──┘ ┴ └───────┘ ┴ ┴ └┘ ┴
src └──┘ └───────┘ └┘
typ ┴ └──┘ ┴ └───────┘ ┴ ┴ └┘ ┴
doc └───────┘
3877 | [] := nil_sublist _
id └┘ └─────────┘
src └┘ └─────────┘
typ └┘ └─────────┘
3878 | (x::l) := begin
id └┘
src └┘
typ └┘
st └─────
3879 by_cases (∀ y ∈ pw_filter R l, R x y),
id └───────┘ ┴ ┴ ┴
src └───────┘ └───┘└───────┘┴ ┴ ┴ ┴ ┴ ┴
typ └───────┘ └───┘└───────┘┴ ┴┴ ┴┴┴┴┴ ┴
doc └───────┘ └───┘└───────┘┴ ┴ ┴ ┴ ┴ ┴
txt └───────┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
par └───────┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
pid ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
st ──────────────────────────────────────┘└─
3880 { rw [pw_filter_cons_of_pos h],
id └───────────────────┘ ┴
src └──┘└───────────────────┘┴ ┴
typ └──┘└───────────────────┘┴┴┴
doc └──┘ ┴ ┴
txt └──┘ ┴ ┴
par └──┘ ┴ ┴
pid └┘ ┴ ┴
st ───┘└─────────────────────────┘└──
3881 exact cons_sublist_cons _ (pw_filter_sublist l) },
id └───────────────┘ └───────────────┘ ┴
src └────┘└───────────────┘└─┘ ┴ └┘
typ └────┘└───────────────┘└─┘ └───────────────┘┴┴└┘
doc └────┘ └─┘ ┴ └┘
txt └────┘ └─┘ ┴ └┘
par └────┘ └─┘ ┴ └┘
pid ┴ └─┘ ┴ ┴┴
st ───────────────────────────────────────────────────┘└┘└
3882 { rw [pw_filter_cons_of_neg h],
id └───────────────────┘ ┴
src └──┘└───────────────────┘┴ ┴
typ └──┘└───────────────────┘┴┴┴
doc └──┘ ┴ ┴
txt └──┘ ┴ ┴
par └──┘ ┴ ┴
pid └┘ ┴ ┴
st ──────────────────────────────┘└──
3883 exact sublist_cons_of_sublist _ (pw_filter_sublist l) },
id └─────────────────────┘ └───────────────┘ ┴
src └────┘└─────────────────────┘└─┘ ┴ └┘
typ └────┘└─────────────────────┘└─┘ └───────────────┘┴┴└┘
doc └────┘ └─┘ ┴ └┘
txt └────┘ └─┘ ┴ └┘
par └────┘ └─┘ ┴ └┘
pid ┴ └─┘ ┴ ┴┴
st ─────────────────────────────────────────────────────────┘└──
3884 end
st ──┘
3885
3886 theorem pw_filter_subset (l : list α) : pw_filter R l ⊆ l :=
id └──┘ ┴ └───────┘ ┴ ┴ ┴ ┴
src └──┘ └───────┘ ┴
typ └──┘ ┴ └───────┘ ┴ ┴ ┴ ┴
doc └───────┘
3887 subset_of_sublist (pw_filter_sublist _)
id └───────────────┘ └───────────────┘
src └───────────────┘ └───────────────┘
typ └───────────────┘ └───────────────┘
3888
3889 theorem pairwise_pw_filter : ∀ (l : list α), pairwise R (pw_filter R l)
id ┴ └──┘ ┴ └──────┘ ┴ └───────┘ ┴ ┴
src └──┘ └──────┘ └───────┘
typ ┴ └──┘ ┴ └──────┘ ┴ └───────┘ ┴ ┴
doc └──────┘ └───────┘
3890 | [] := pairwise.nil
id └┘ └──────────┘
src └┘ └──────────┘
typ └┘ └──────────┘
3891 | (x::l) := begin
id └┘
src └┘
typ └┘
st └─────
3892 by_cases (∀ y ∈ pw_filter R l, R x y),
id └───────┘ ┴ ┴ ┴
src └───────┘ └───┘└───────┘┴ ┴ ┴ ┴ ┴ ┴
typ └───────┘ └───┘└───────┘┴ ┴┴ ┴┴┴┴┴ ┴
doc └───────┘ └───┘└───────┘┴ ┴ ┴ ┴ ┴ ┴
txt └───────┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
par └───────┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
pid ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴
st ──────────────────────────────────────┘└─
3893 { rw [pw_filter_cons_of_pos h],
id └───────────────────┘ ┴
src └──┘└───────────────────┘┴ ┴
typ └──┘└───────────────────┘┴┴┴
doc └──┘ ┴ ┴
txt └──┘ ┴ ┴
par └──┘ ┴ ┴
pid └┘ ┴ ┴
st ───┘└─────────────────────────┘└──
3894 exact pairwise_cons.2 ⟨h, pairwise_pw_filter l⟩ },
id └───────────┘ ┴ └────────────────┘ ┴
src └────┘└───────────┘└─┘ └┘ ┴ └┘
typ └────┘└───────────┘└─┘ ┴└┘└────────────────┘┴┴└┘
doc └────┘ └─┘ └┘ ┴ └┘
txt └────┘ └─┘ └┘ ┴ └┘
par └────┘ └─┘ └┘ ┴ └┘
pid ┴ └─┘ └┘ ┴ ┴┴
st ───────────────────────────────────────────────────┘└┘└
3895 { rw [pw_filter_cons_of_neg h],
id └───────────────────┘ ┴
src └──┘└───────────────────┘┴ ┴
typ └──┘└───────────────────┘┴┴┴
doc └──┘ ┴ ┴
txt └──┘ ┴ ┴
par └──┘ ┴ ┴
pid └┘ ┴ ┴
st ──────────────────────────────┘└──
3896 exact pairwise_pw_filter l },
id └────────────────┘ ┴
src └────┘ ┴ ┴
typ └────┘└────────────────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ──────────────────────────────┘└──
3897 end
st ──┘
3898
3899 theorem pw_filter_eq_self {l : list α} : pw_filter R l = l ↔ pairwise R l :=
id └──┘ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴
src └──┘ └───────┘ ┴ ┴ └──────┘
typ └──┘ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └───────┘ └──────┘
3900 ⟨λ e, e ▸ pairwise_pw_filter l, λ p, begin
id ┴ ┴ ┴ └────────────────┘ ┴ ┴
src ┴ └────────────────┘
typ ┴ ┴ ┴ └────────────────┘ ┴ ┴
st └─────
3901 induction l with x l IH, {refl},
id ┴
src └────────┘ └──────────┘ └──┘
typ └────────┘┴└──────────┘ └──┘
doc └────────┘ └──────────┘ └──┘
txt └────────┘ └──────────┘ └──┘
par └────────┘ └──────────┘ └──┘
pid ┴ ┴└─────────┘
st ────────────────────────┘└─────┘└┘└
3902 cases pairwise_cons.1 p with al p,
id └───────────┘ ┴
src └────┘└───────────┘└─┘ └────────┘
typ └────┘└───────────┘└─┘┴└────────┘
doc └────┘ └─┘ └────────┘
txt └────┘ └─┘ └────────┘
par └────┘ └─┘ └────────┘
pid ┴ └─┘ └────────┘
st ──────────────────────────────────┘└─
3903 rw [pw_filter_cons_of_pos (ball.imp_left (pw_filter_subset l) al), IH p],
id └───────────────────┘ └───────────┘ └──────────────┘ ┴ └┘ └┘ ┴
src └──┘└───────────────────┘┴ └───────────┘┴ └──────────────┘┴ └┘ └─┘ ┴ ┴
typ └──┘└───────────────────┘┴ └───────────┘┴ └──────────────┘┴┴└┘└┘└─┘└┘┴┴┴
doc └──┘ ┴ ┴ ┴ └┘ └─┘ ┴ ┴
txt └──┘ ┴ ┴ ┴ └┘ └─┘ ┴ ┴
par └──┘ ┴ ┴ ┴ └┘ └─┘ ┴ ┴
pid └┘ ┴ ┴ ┴ └┘ └─┘ ┴ ┴
st ──────────────────────────────────────────────────────────────────┘└────┘└──
3904 end⟩
st ──┘
3905
3906 @[simp] theorem pw_filter_idempotent {l : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
3907 pw_filter R (pw_filter R l) = pw_filter R l :=
id └───────┘ ┴ └───────┘ ┴ ┴ ┴ └───────┘ ┴ ┴
src └───────┘ └───────┘ ┴ └───────┘
typ └───────┘ ┴ └───────┘ ┴ ┴ ┴ └───────┘ ┴ ┴
doc └───────┘ └───────┘ └───────┘
3908 pw_filter_eq_self.mpr (pairwise_pw_filter l)
id └───────────────┘└──┘ └────────────────┘ ┴
src └───────────────┘└──┘ └────────────────┘
typ └───────────────┘└──┘ └────────────────┘ ┴
3909
3910 theorem forall_mem_pw_filter (neg_trans : ∀ {x y z}, R x z → R x y ∨ R y z)
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
3911 (a : α) (l : list α) : (∀ b ∈ pw_filter R l, R a b) ↔ (∀ b ∈ l, R a b) :=
id ┴ └──┘ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └───────┘ ┴
typ ┴ └──┘ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └───────┘
3912 ⟨begin
st └─────
3913 induction l with x l IH, { exact λ _ _, false.elim },
id ┴ └────────┘
src └────────┘ └──────────┘ └────┘ └────┘└────────┘┴
typ └────────┘┴└──────────┘ └────┘ └────┘└────────┘┴
doc └────────┘ └──────────┘ └────┘ └────┘ ┴
txt └────────┘ └──────────┘ └────┘ └────┘ ┴
par └────────┘ └──────────┘ └────┘ └────┘ ┴
pid ┴ ┴└─────────┘ ┴ └────┘ ┴
st ────────────────────────┘└──┘└──────────────────────┘└┘└
3914 simp only [forall_mem_cons],
id └─────────────┘
src └─────────┘└─────────────┘┴
typ └─────────┘└─────────────┘┴
doc └─────────┘ ┴
txt └─────────┘ ┴
par └─────────┘ ┴
pid ┴└──┘└┘ ┴
st ────────────────────────────┘└─
3915 by_cases (∀ y ∈ pw_filter R l, R x y); dsimp at h,
id └───────┘ ┴ ┴ ┴
src └───────┘ └───┘└───────┘┴ ┴ ┴ ┴ ┴ ┴ └────────┘
typ └───────┘ └───┘└───────┘┴ ┴┴ ┴┴┴┴┴ ┴ └────────┘
doc └───────┘ └───┘└───────┘┴ ┴ ┴ ┴ ┴ ┴ └────────┘
txt └───────┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ └────────┘
par └───────┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ └────────┘
pid ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴└──┘
st ──────────────────────────────────────────────────┘└─
3916 { simp only [pw_filter_cons_of_pos h, forall_mem_cons, and_imp],
id └───────────────────┘ ┴ └─────────────┘ └─────┘
src └─────────┘└───────────────────┘┴ └┘└─────────────┘└┘└─────┘┴
typ └─────────┘└───────────────────┘┴┴└┘└─────────────┘└┘└─────┘┴
doc └─────────┘ ┴ └┘ └┘ ┴
txt └─────────┘ ┴ └┘ └┘ ┴
par └─────────┘ ┴ └┘ └┘ ┴
pid ┴└──┘└┘ ┴ └┘ └┘ ┴
st ───┘└───────────────────────────────────────────────────────────┘└─
3917 exact λ r H, ⟨r, IH H⟩ },
id └┘
src └────┘ └────┘ └┘ ┴ └┘
typ └────┘ └────┘ └┘└┘┴ └┘
doc └────┘ └────┘ └┘ ┴ └┘
txt └────┘ └────┘ └┘ ┴ └┘
par └────┘ └────┘ └┘ ┴ └┘
pid ┴ └────┘ └┘ ┴ ┴┴
st ──────────────────────────┘└┘└
3918 { rw [pw_filter_cons_of_neg h],
id └───────────────────┘ ┴
src └──┘└───────────────────┘┴ ┴
typ └──┘└───────────────────┘┴┴┴
doc └──┘ ┴ ┴
txt └──┘ ┴ ┴
par └──┘ ┴ ┴
pid └┘ ┴ ┴
st ──────────────────────────────┘└──
3919 refine λ H, ⟨_, IH H⟩,
id └┘
src └─────┘ └──┘ └─┘ ┴ ┴
typ └─────┘ └──┘ └─┘└┘┴ ┴
doc └─────┘ └──┘ └─┘ ┴ ┴
txt └─────┘ └──┘ └─┘ ┴ ┴
par └─────┘ └──┘ └─┘ ┴ ┴
pid ┴ └──┘ └─┘ ┴ ┴
st ────────────────────────┘└─
3920 cases e : find (λ y, ¬ R x y) (pw_filter R l) with k,
id └──┘ ┴ └───────┘ ┴ ┴
src └────┘ └─┘└──┘┴ └──┘ ┴ ┴ ┴ └┘ └───────┘┴ ┴ └──────┘
typ └────┘ └─┘└──┘┴ └──┘ ┴ ┴┴┴ └┘ └───────┘┴┴┴┴└──────┘
doc └────┘ └─┘└──┘┴ └──┘ ┴ ┴ ┴ └┘ └───────┘┴ ┴ └──────┘
txt └────┘ └─┘ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └──────┘
par └────┘ └─┘ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ └──────┘
pid ┴ └─┘ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴└─────┘
st ───────────────────────────────────────────────────────┘└─
3921 { refine h.elim (ball.imp_right _ (find_eq_none.1 e)),
id └────┘ └────────────┘ └──────────┘ ┴
src └─────┘└────┘┴ └────────────┘└─┘ └──────────┘└─┘ └┘
typ └─────┘└────┘┴ └────────────┘└─┘ └──────────┘└─┘┴└┘
doc └─────┘ ┴ └─┘ └─┘ └┘
txt └─────┘ ┴ └─┘ └─┘ └┘
par └─────┘ ┴ └─┘ └─┘ └┘
pid ┴ ┴ └─┘ └─┘ └┘
st ─────┘└─────────────────────────────────────────────────┘└─
3922 exact λ y _, not_not.1 },
id └─────┘
src └────┘ └────┘└─────┘└─┘
typ └────┘ └────┘└─────┘└─┘
doc └────┘ └────┘ └─┘
txt └────┘ └────┘ └─┘
par └────┘ └────┘ └─┘
pid ┴ └────┘ └─┘
st ────────────────────────────┘└┘└
3923 { have := find_some e,
id └───────┘ ┴
src └──────┘└───────┘┴
typ └──────┘└───────┘┴┴
doc └──────┘ ┴
txt └──────┘ ┴
par └──────┘ ┴
pid └───┘└─┘ ┴
st ────────────────────────┘└─
3924 exact (neg_trans (H k (find_mem e))).resolve_right this } }
id └───────┘ ┴ ┴ └──────┘ ┴ └──┘
src └────┘ ┴ ┴ ┴ └──────┘┴ └────────────────┘ ┴
typ └────┘ └───────┘┴ ┴┴┴┴ └──────┘┴┴└────────────────┘└──┘┴
doc └────┘ ┴ ┴ ┴ ┴ └────────────────┘ ┴
txt └────┘ ┴ ┴ ┴ ┴ └────────────────┘ ┴
par └────┘ ┴ ┴ ┴ ┴ └────────────────┘ ┴
pid ┴ ┴ ┴ ┴ ┴ └────────────────┘ ┴
st ─────────────────────────────────────────────────────────────┘└───
3925 end, ball.imp_left (pw_filter_subset l)⟩
id └───────────┘ └──────────────┘ ┴
src └───────────┘ └──────────────┘
typ └───────────┘ └──────────────┘ ┴
st ──┘
3926
3927 end pairwise
3928
3929 /- chain relation (conjunction of R a b ∧ R b c ∧ R c d ...) -/
3930
3931 section chain
3932
3933 run_cmd tactic.mk_iff_of_inductive_prop `list.chain `list.chain_iff
id └─────────────────────────────┘ ┴ ┴
src └─────────────────────────────┘ ┴ ┴
typ └─────────────────────────────┘ ┴ ┴
doc └─────────────────────────────┘
3934
3935 variable {R : α → α → Prop}
3936
3937 theorem rel_of_chain_cons {a b : α} {l : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3938 (p : chain R a (b::l)) : R a b :=
id └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴
src └───┘ └┘
typ └───┘ ┴ ┴ ┴└┘┴ ┴ ┴ ┴
doc └───┘
3939 (chain_cons.1 p).1
id └────────┘┴ ┴ ┴
src └────────┘┴ ┴
typ └────────┘┴ ┴ ┴
3940
3941 theorem chain_of_chain_cons {a b : α} {l : list α}
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3942 (p : chain R a (b::l)) : chain R b l :=
id └───┘ ┴ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴
src └───┘ └┘ └───┘
typ └───┘ ┴ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴
doc └───┘ └───┘
3943 (chain_cons.1 p).2
id └────────┘┴ ┴ ┴
src └────────┘┴ ┴
typ └────────┘┴ ┴ ┴
3944
3945 theorem chain.imp {S : α → α → Prop}
id ┴ ┴
typ ┴ ┴
3946 (H : ∀ a b, R a b → S a b) {a : α} {l : list α} (p : chain R a l) : chain S a l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └──┘ └───┘ └───┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc └───┘ └───┘
3947 by induction p with _ a b l r p IH; constructor;
id ┴
src └────────┘ └──────────────────┘ └─────────┘
typ └────────┘┴└──────────────────┘ └─────────┘
doc └────────┘ └──────────────────┘ └─────────┘
txt └────────┘ └──────────────────┘ └─────────┘
par └────────┘ └──────────────────┘ └─────────┘
pid ┴ ┴└─────────────────┘
st └──────────────────────────────────────────────
3948 [exact H _ _ r, exact IH]
id ┴ ┴ ┴ └┘
src ┴└────┘ └───┘ └────┘
typ ┴└────┘┴└───┘┴ └────┘└┘
doc └────┘ └───┘ └────┘
txt └────┘ └───┘ └────┘
par └────┘ └───┘ └────┘
pid ┴ └───┘ ┴
st ───────────────────────────┘
3949
3950 theorem chain.iff {S : α → α → Prop}
id ┴ ┴
typ ┴ ┴
3951 (H : ∀ a b, R a b ↔ S a b) {a : α} {l : list α} : chain R a l ↔ chain S a l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src ┴ └──┘ └───┘ ┴ └───┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc └───┘ └───┘
3952 ⟨chain.imp (λ a b, (H a b).1), chain.imp (λ a b, (H a b).2)⟩
id └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └───────┘ ┴ └───────┘ ┴
typ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴ ┴
3953
3954 theorem chain.iff_mem {a : α} {l : list α} :
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
3955 chain R a l ↔ chain (λ x y, x ∈ a :: l ∧ y ∈ l ∧ R x y) a l :=
id └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └───┘ ┴ └───┘ ┴ └┘ ┴ ┴ ┴
typ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └───┘ └───┘
3956 ⟨λ p, by induction p with _ a b l r p IH; constructor;
id ┴ ┴
src └────────┘ └──────────────────┘ └─────────┘
typ ┴ └────────┘┴└──────────────────┘ └─────────┘
doc └────────┘ └──────────────────┘ └─────────┘
txt └────────┘ └──────────────────┘ └─────────┘
par └────────┘ └──────────────────┘ └─────────┘
pid ┴ ┴└─────────────────┘
st └──────────────────────────────────────────────
3957 [exact ⟨mem_cons_self _ _, mem_cons_self _ _, r⟩,
id ┴ └───────────┘ ┴
src ┴└────┘ └────┘└───────────┘└────┘ ┴
typ ┴└────┘ └────┘└───────────┘└────┘┴┴
doc └────┘ └────┘ └────┘ ┴
txt └────┘ └────┘ └────┘ ┴
par └────┘ └────┘ └────┘ ┴
pid ┴ └────┘ └────┘ ┴
st ────────────────────────────────────────────────────
3958 exact IH.imp (λ a b ⟨am, bm, h⟩,
id └────┘ └┘ └┘ ┴
src └────┘└────┘┴ └────┘ └┘ └┘ └──
typ └────┘└────┘┴ └────┘└┘└┘└┘└┘┴└──
doc └────┘ ┴ └────┘ └┘ └┘ └──
txt └────┘ ┴ └────┘ └┘ └┘ └──
par └────┘ ┴ └────┘ └┘ └┘ └──
pid ┴ ┴ └────┘ └┘ └┘ └──
st ────────────────────────────────────
3959 ⟨mem_cons_of_mem _ am, mem_cons_of_mem _ bm, h⟩)],
id └─────────────┘
src ───┘ └─┘ └┘└─────────────┘└─┘ └┘ └┘
typ ───┘ └─┘ └┘└─────────────┘└─┘ └┘ └┘
doc ───┘ └─┘ └┘ └─┘ └┘ └┘
txt ───┘ └─┘ └┘ └─┘ └┘ └┘
par ───┘ └─┘ └┘ └─┘ └┘ └┘
pid ───┘ └─┘ └┘ └─┘ └┘ └┘
st ────────────────────────────────────────────────────┘
3960 chain.imp (λ a b h, h.2.2)⟩
id └───────┘ ┴ ┴ ┴ ┴┴ ┴
src └───────┘ ┴ ┴
typ └───────┘ ┴ ┴ ┴ ┴┴ ┴
3961
3962 theorem chain_singleton {a b : α} : chain R a [b] ↔ R a b :=
id ┴ └───┘ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴
src └───┘ ┴ ┴ ┴
typ ┴ └───┘ ┴ ┴ ┴┴┴ ┴ ┴ ┴ ┴
doc └───┘
3963 by simp only [chain_cons, chain.nil, and_true]
id └────────┘ └───────┘ └──────┘
src └─────────┘└────────┘└┘└───────┘└┘└──────┘└─
typ └─────────┘└────────┘└┘└───────┘└┘└──────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────
3964
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3965 theorem chain_split {a b : α} {l₁ l₂ : list α} : chain R a (l₁++b::l₂) ↔
id ┴ └──┘ ┴ └───┘ ┴ ┴ └┘└┘┴└┘└┘ ┴
src └──┘ └───┘ └┘ └┘ ┴
typ ┴ └──┘ ┴ └───┘ ┴ ┴ └┘└┘┴└┘└┘ ┴
doc └───┘
3966 chain R a (l₁++[b]) ∧ chain R b l₂ :=
id └───┘ ┴ ┴ └┘└┘┴┴┴ ┴ └───┘ ┴ ┴ └┘
src └───┘ └┘┴ ┴ ┴ └───┘
typ └───┘ ┴ ┴ └┘└┘┴┴┴ ┴ └───┘ ┴ ┴ └┘
doc └───┘ └───┘
3967 by induction l₁ with x l₁ IH generalizing a;
id └┘
src └────────┘ └──────────────────────────┘
typ └────────┘└┘└──────────────────────────┘
doc └────────┘ └──────────────────────────┘
txt └────────┘ └──────────────────────────┘
par └────────┘ └──────────────────────────┘
pid ┴ ┴└──────────┘└─────────────┘
st └──────────────────────────────────────────
3968 simp only [*, nil_append, cons_append, chain.nil, chain_cons, and_true, and_assoc]
id └────────┘ └─────────┘ └───────┘ └────────┘ └──────┘ └───────┘
src └────────────┘└────────┘└┘└─────────┘└┘└───────┘└┘└────────┘└┘└──────┘└┘└───────┘└─
typ └────────────┘└────────┘└┘└─────────┘└┘└───────┘└┘└────────┘└┘└──────┘└┘└───────┘└─
doc └────────────┘ └┘ └┘ └┘ └┘ └┘ └─
txt └────────────┘ └┘ └┘ └┘ └┘ └┘ └─
par └────────────┘ └┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└───┘ └┘ └┘ └┘ └┘ └┘ ┴└
st ───────────────────────────────────────────────────────────────────────────────────
3969
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3970 theorem chain_map (f : β → α) {b : β} {l : list β} :
id ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ └──┘ ┴
3971 chain R (f b) (map f l) ↔ chain (λ a b : β, R (f a) (f b)) b l :=
id └───┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └───┘ └─┘ ┴ └───┘
typ └───┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └───┘ └───┘
3972 by induction l generalizing b; simp only [map, chain.nil, chain_cons, *]
id ┴ └─┘ └───────┘ └────────┘
src └────────┘ └─────────────┘ └─────────┘└─┘└┘└───────┘└┘└────────┘└────
typ └────────┘┴└─────────────┘ └─────────┘└─┘└┘└───────┘└┘└────────┘└────
doc └────────┘ └─────────────┘ └─────────┘ └┘ └┘ └────
txt └────────┘ └─────────────┘ └─────────┘ └┘ └┘ └────
par └────────┘ └─────────────┘ └─────────┘ └┘ └┘ └────
pid ┴ ┴└────────────┘ ┴└──┘└┘ └┘ └┘ └──┘└
st └──────────────────────────────────────────────────────────────────────
3973
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
3974 theorem chain_of_chain_map {S : β → β → Prop} (f : α → β)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
3975 (H : ∀ a b : α, S (f a) (f b) → R a b) {a : α} {l : list α}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
3976 (p : chain S (f a) (map f l)) : chain R a l :=
id └───┘ ┴ ┴ ┴ └─┘ ┴ ┴ └───┘ ┴ ┴ ┴
src └───┘ └─┘ └───┘
typ └───┘ ┴ ┴ ┴ └─┘ ┴ ┴ └───┘ ┴ ┴ ┴
doc └───┘ └───┘
3977 ((chain_map f).1 p).imp H
id └───────┘ ┴ ┴ ┴ └─┘ ┴
src └───────┘ ┴ └─┘
typ └───────┘ ┴ ┴ ┴ └─┘ ┴
3978
3979 theorem chain_map_of_chain {S : β → β → Prop} (f : α → β)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
3980 (H : ∀ a b : α, R a b → S (f a) (f b)) {a : α} {l : list α}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
3981 (p : chain R a l) : chain S (f a) (map f l) :=
id └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └───┘ └───┘ └─┘
typ └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ └─┘ ┴ ┴
doc └───┘ └───┘
3982 (chain_map f).2 $ p.imp H
id └───────┘ ┴ ┴ ┴└──┘ ┴
src └───────┘ ┴ └──┘
typ └───────┘ ┴ ┴ ┴└──┘ ┴
3983
3984 theorem chain_of_pairwise {a : α} {l : list α} (p : pairwise R (a::l)) : chain R a l :=
id ┴ └──┘ ┴ └──────┘ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴
src └──┘ └──────┘ └┘ └───┘
typ ┴ └──┘ ┴ └──────┘ ┴ ┴└┘┴ └───┘ ┴ ┴ ┴
doc └──────┘ └───┘
3985 begin
st └─────
3986 cases pairwise_cons.1 p with r p', clear p,
id └───────────┘ ┴
src └────┘└───────────┘└─┘ └────────┘ └─────┘
typ └────┘└───────────┘└─┘┴└────────┘ └─────┘
doc └────┘ └─┘ └────────┘ └─────┘
txt └────┘ └─┘ └────────┘ └─────┘
par └────┘ └─┘ └────────┘ └─────┘
pid ┴ └─┘ └────────┘ └┘
st ──────────────────────────────────┘└───────┘└─
3987 induction p' with b l r' p IH generalizing a, {exact chain.nil},
id └┘ └───────┘
src └────────┘ └──────────────────────────────┘ └────┘└───────┘
typ └────────┘└┘└──────────────────────────────┘ └────┘└───────┘
doc └────────┘ └──────────────────────────────┘ └────┘
txt └────────┘ └──────────────────────────────┘ └────┘
par └────────┘ └──────────────────────────────┘ └────┘
pid ┴ ┴└──────────────┘└─────────────┘ ┴
st ─────────────────────────────────────────────┘└────────────────┘└┘└
3988 simp only [chain_cons, forall_mem_cons] at r,
id └────────┘ └─────────────┘
src └─────────┘└────────┘└┘└─────────────┘└────┘
typ └─────────┘└────────┘└┘└─────────────┘└────┘
doc └─────────┘ └┘ └────┘
txt └─────────┘ └┘ └────┘
par └─────────┘ └┘ └────┘
pid ┴└──┘└┘ └┘ ┴┴└──┘
st ─────────────────────────────────────────────┘└─
3989 exact chain_cons.2 ⟨r.1, IH r'⟩
id └────────┘ ┴ └┘ └┘
src └────┘└────────┘└─┘ └──┘ ┴ └┘
typ └────┘└────────┘└─┘ ┴└──┘└┘┴└┘└┘
doc └────┘ └─┘ └──┘ ┴ └┘
txt └────┘ └─┘ └──┘ ┴ └┘
par └────┘ └─┘ └──┘ ┴ └┘
pid ┴ └─┘ └──┘ ┴ ┴┴
st ─────────────────────────────────┘
3990 end
st └─┘
3991
3992 theorem chain_iff_pairwise (tr : transitive R) {a : α} {l : list α} :
id └────────┘ ┴ ┴ └──┘ ┴
src └────────┘ └──┘
typ └────────┘ ┴ ┴ └──┘ ┴
3993 chain R a l ↔ pairwise R (a::l) :=
id └───┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴└┘┴
src └───┘ ┴ └──────┘ └┘
typ └───┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴└┘┴
doc └───┘ └──────┘
3994 ⟨λ c, begin
id ┴
typ ┴
st └─────
3995 induction c with b b c l r p IH, {exact pairwise_singleton _ _},
id ┴ └────────────────┘
src └────────┘ └──────────────────┘ └────┘└────────────────┘└──┘
typ └────────┘┴└──────────────────┘ └────┘└────────────────┘└──┘
doc └────────┘ └──────────────────┘ └────┘ └──┘
txt └────────┘ └──────────────────┘ └────┘ └──┘
par └────────┘ └──────────────────┘ └────┘ └──┘
pid ┴ ┴└─────────────────┘ ┴ └──┘
st ────────────────────────────────┘└─────────────────────────────┘└┘└
3996 apply IH.cons _, simp only [mem_cons_iff, forall_mem_cons', r, true_and],
id └─────┘ └──────────┘ └──────────────┘ ┴ └──────┘
src └────┘└─────┘└┘ └─────────┘└──────────┘└┘└──────────────┘└┘ └┘└──────┘┴
typ └────┘└─────┘└┘ └─────────┘└──────────┘└┘└──────────────┘└┘┴└┘└──────┘┴
doc └────┘ └┘ └─────────┘ └┘ └┘ └┘ ┴
txt └────┘ └┘ └─────────┘ └┘ └┘ └┘ ┴
par └────┘ └┘ └─────────┘ └┘ └┘ └┘ ┴
pid ┴ └┘ ┴└──┘└┘ └┘ └┘ └┘ ┴
st ────────────────┘└───────────────────────────────────────────────────────┘└─
3997 show ∀ x ∈ l, R b x, from λ x m, (tr r (rel_of_pairwise_cons IH m)),
id ┴ ┴ ┴ └┘ ┴ └──────────────────┘ └┘
src └───┘ └───┘ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ └──────────────────┘┴ ┴ └┘
typ └───┘ └───┘┴ ┴┴┴┴┴ └───┘ └────┘ └┘┴┴┴ └──────────────────┘┴└┘┴ └┘
doc └───┘ └───┘ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ ┴ ┴ └┘
txt └───┘ └───┘ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ ┴ ┴ └┘
par └───┘ └───┘ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ ┴ ┴ └┘
pid └───┘ └───┘ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ ┴ ┴ └┘
st ────────────────────────────────────────────────────────────────────┘└─
3998 end, chain_of_pairwise⟩
id └───────────────┘
src └───────────────┘
typ └───────────────┘
st ──┘
3999
4000 theorem chain'.imp {S : α → α → Prop}
id ┴ ┴
typ ┴ ┴
4001 (H : ∀ a b, R a b → S a b) {l : list α} (p : chain' R l) : chain' S l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └────┘ ┴ ┴
src └──┘ └────┘ └────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └────┘ ┴ ┴
doc └────┘ └────┘
4002 by cases l; [trivial, exact p.imp H]
id ┴ ┴ └───┘ ┴
src └────┘ ┴└─────┘ └────┘└───┘┴
typ └────┘┴ ┴└─────┘ └────┘└───┘┴┴
doc └────┘ └─────┘ └────┘ ┴
txt └────┘ └─────┘ └────┘ ┴
par └────┘ └─────┘ └────┘ ┴
pid ┴ ┴ ┴
st └────────────────────────────────┘
4003
4004 theorem chain'.iff {S : α → α → Prop}
id ┴ ┴
typ ┴ ┴
4005 (H : ∀ a b, R a b ↔ S a b) {l : list α} : chain' R l ↔ chain' S l :=
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
src ┴ └──┘ └────┘ ┴ └────┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴
doc └────┘ └────┘
4006 ⟨chain'.imp (λ a b, (H a b).1), chain'.imp (λ a b, (H a b).2)⟩
id └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └────────┘ ┴ └────────┘ ┴
typ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴ └────────┘ ┴ ┴ ┴ ┴ ┴ ┴
4007
4008 theorem chain'.iff_mem : ∀ {l : list α}, chain' R l ↔ chain' (λ x y, x ∈ l ∧ y ∈ l ∧ R x y) l
id ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ └────┘ ┴ └────┘ ┴ ┴ ┴ ┴
typ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └────┘ └────┘
4009 | [] := iff.rfl
id └┘ └─────┘
src └┘ └─────┘
typ └┘ └─────┘
4010 | (x::l) :=
id └┘
src └┘
typ └┘
4011 ⟨λ h, (chain.iff_mem.1 h).imp $ λ a b ⟨h₁, h₂, h₃⟩, ⟨h₁, or.inr h₂, h₃⟩,
id ┴ └───────────┘┴ ┴ └─┘ ┴ ┴ ┴└┘ └┘ └┘ └────┘
src └───────────┘┴ └─┘ └────┘
typ ┴ └───────────┘┴ ┴ └─┘ ┴ ┴ ┴└┘ └┘ └┘ └────┘
4012 chain'.imp $ λ a b h, h.2.2⟩
id └────────┘ ┴ ┴ ┴ ┴┴ ┴
src └────────┘ ┴ ┴
typ └────────┘ ┴ ┴ ┴ ┴┴ ┴
4013
4014 theorem chain'_singleton (a : α) : chain' R [a] := chain.nil
id ┴ └────┘ ┴ ┴┴┴ └───────┘
src └────┘ ┴ ┴ └───────┘
typ ┴ └────┘ ┴ ┴┴┴ └───────┘
doc └────┘
4015
4016 theorem chain'_split {a : α} : ∀ {l₁ l₂ : list α}, chain' R (l₁++a::l₂) ↔
id ┴ ┴ └──┘ ┴ └────┘ ┴ └┘└┘┴└┘└┘ ┴
src └──┘ └────┘ └┘ └┘ ┴
typ ┴ ┴ └──┘ ┴ └────┘ ┴ └┘└┘┴└┘└┘ ┴
doc └────┘
4017 chain' R (l₁++[a]) ∧ chain' R (a::l₂)
id └────┘ ┴ └┘└┘┴┴┴ ┴ └────┘ ┴ ┴└┘└┘
src └────┘ └┘┴ ┴ ┴ └────┘ └┘
typ └────┘ ┴ └┘└┘┴┴┴ ┴ └────┘ ┴ ┴└┘└┘
doc └────┘ └────┘
4018 | [] l₂ := (and_iff_right (chain'_singleton a)).symm
id └┘ └───────────┘ └──────────────┘ ┴ └──┘
src └┘ └───────────┘ └──────────────┘ └──┘
typ └┘ └───────────┘ └──────────────┘ ┴ └──┘
4019 | (b::l₁) l₂ := chain_split
id └┘ └─────────┘
src └┘ └─────────┘
typ └┘ └─────────┘
4020
4021 theorem chain'_map (f : β → α) {l : list β} :
id ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ └──┘ ┴
4022 chain' R (map f l) ↔ chain' (λ a b : β, R (f a) (f b)) l :=
id └────┘ ┴ └─┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └────┘ └─┘ ┴ └────┘
typ └────┘ ┴ └─┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └────┘ └────┘
4023 by cases l; [refl, exact chain_map _]
id ┴ ┴ └───────┘
src └────┘ ┴└──┘ └────┘└───────┘└┘
typ └────┘┴ ┴└──┘ └────┘└───────┘└┘
doc └────┘ └──┘ └────┘ └┘
txt └────┘ └──┘ └────┘ └┘
par └────┘ └──┘ └────┘ └┘
pid ┴ ┴ └┘
st └─────────────────────────────────┘
4024
4025 theorem chain'_of_chain'_map {S : β → β → Prop} (f : α → β)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
4026 (H : ∀ a b : α, S (f a) (f b) → R a b) {l : list α}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
4027 (p : chain' S (map f l)) : chain' R l :=
id └────┘ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴
src └────┘ └─┘ └────┘
typ └────┘ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴
doc └────┘ └────┘
4028 ((chain'_map f).1 p).imp H
id └────────┘ ┴ ┴ ┴ └─┘ ┴
src └────────┘ ┴ └─┘
typ └────────┘ ┴ ┴ ┴ └─┘ ┴
4029
4030 theorem chain'_map_of_chain' {S : β → β → Prop} (f : α → β)
id ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
4031 (H : ∀ a b : α, R a b → S (f a) (f b)) {l : list α}
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
4032 (p : chain' R l) : chain' S (map f l) :=
id └────┘ ┴ ┴ └────┘ ┴ └─┘ ┴ ┴
src └────┘ └────┘ └─┘
typ └────┘ ┴ ┴ └────┘ ┴ └─┘ ┴ ┴
doc └────┘ └────┘
4033 (chain'_map f).2 $ p.imp H
id └────────┘ ┴ ┴ ┴└──┘ ┴
src └────────┘ ┴ └──┘
typ └────────┘ ┴ ┴ ┴└──┘ ┴
4034
4035 theorem chain'_of_pairwise : ∀ {l : list α}, pairwise R l → chain' R l
id ┴ └──┘ ┴ └──────┘ ┴ ┴ └────┘ ┴ ┴
src └──┘ └──────┘ └────┘
typ ┴ └──┘ ┴ └──────┘ ┴ ┴ └────┘ ┴ ┴
doc └──────┘ └────┘
4036 | [] _ := trivial
id └┘ └─────┘
src └┘ └─────┘
typ └┘ └─────┘
4037 | (a::l) h := chain_of_pairwise h
id └┘ ┴ └───────────────┘
src └┘ └───────────────┘
typ └┘ ┴ └───────────────┘
4038
4039 theorem chain'_iff_pairwise (tr : transitive R) : ∀ {l : list α},
id └────────┘ ┴ ┴ └──┘ ┴
src └────────┘ └──┘
typ └────────┘ ┴ ┴ └──┘ ┴
4040 chain' R l ↔ pairwise R l
id └────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
src └────┘ ┴ └──────┘
typ └────┘ ┴ ┴ ┴ └──────┘ ┴ ┴
doc └────┘ └──────┘
4041 | [] := (iff_true_intro pairwise.nil).symm
id └┘ └────────────┘ └──────────┘ └──┘
src └┘ └────────────┘ └──────────┘ └──┘
typ └┘ └────────────┘ └──────────┘ └──┘
4042 | (a::l) := chain_iff_pairwise tr
id └┘ └────────────────┘ └┘
src └┘ └────────────────┘
typ └┘ └────────────────┘ └┘
4043
4044 end chain
4045
4046 /- no duplicates predicate -/
4047
4048 section nodup
4049
4050 @[simp] theorem forall_mem_ne {a : α} {l : list α} : (∀ (a' : α), a' ∈ l → ¬a = a') ↔ a ∉ l :=
id ┴ └──┘ ┴ ┴ └┘ ┴ ┴ ┴┴ ┴ └┘ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ └┘ ┴ ┴ ┴┴ ┴ └┘ ┴ ┴ ┴ ┴
doc └──┘
4051 ⟨λ h m, h _ m rfl, λ h a' m e, h (e.symm ▸ m)⟩
id ┴ ┴ ┴ ┴ └─┘ ┴ └┘ ┴ ┴ ┴ ┴└───┘ ┴ ┴
src └─┘ └───┘ ┴
typ ┴ ┴ ┴ ┴ └─┘ ┴ └┘ ┴ ┴ ┴ ┴└───┘ ┴ ┴
4052
4053 @[simp] theorem nodup_nil : @nodup α [] := pairwise.nil
id └───┘ ┴ └┘ └──────────┘
src └───┘ └┘ └──────────┘
typ └───┘ ┴ └┘ └──────────┘
doc └──┘ └───┘
4054
4055 @[simp] theorem nodup_cons {a : α} {l : list α} : nodup (a::l) ↔ a ∉ l ∧ nodup l :=
id ┴ └──┘ ┴ └───┘ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ └───┘ ┴
src └──┘ └───┘ └┘ ┴ ┴ ┴ └───┘
typ ┴ └──┘ ┴ └───┘ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ └───┘ ┴
doc └──┘ └───┘ └───┘
4056 by simp only [nodup, pairwise_cons, forall_mem_ne]
id └───┘ └───────────┘ └───────────┘
src └─────────┘└───┘└┘└───────────┘└┘└───────────┘└─
typ └─────────┘└───┘└┘└───────────┘└┘└───────────┘└─
doc └─────────┘└───┘└┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────
4057
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4058 lemma rel_nodup {r : α → β → Prop} (hr : relator.bi_unique r) : (forall₂ r ⇒ (↔)) nodup nodup
id ┴ ┴ └───────────────┘ ┴ └─────┘ ┴ ┴ ┴ └───┘ └───┘
src └───────────────┘ └─────┘ ┴ ┴ └───┘ └───┘
typ ┴ ┴ └───────────────┘ ┴ └─────┘ ┴ ┴ ┴ └───┘ └───┘
doc └───┘ └───┘
4059 | _ _ forall₂.nil := by simp only [nodup_nil]
id └─────────┘ └───────┘
src └─────────┘ └─────────┘└───────┘└┘
typ └─────────┘ └─────────┘└───────┘└┘
doc └─────────┘ └┘
txt └─────────┘ └┘
par └─────────┘ └┘
pid ┴└──┘└┘ ┴┴
st └─────────────────────┘
4060 | _ _ (forall₂.cons hab h) :=
id └──────────┘
src └──────────┘
typ └──────────┘
4061 by simpa only [nodup_cons] using relator.rel_and (relator.rel_not (rel_mem hr hab h)) (rel_nodup h)
id └────────┘ └─────────────┘ └─────────────┘ └─────┘ └┘ └─┘ └───────┘ ┴
src └──────────┘└────────┘└──────┘└─────────────┘┴ └─────────────┘┴ └─────┘┴ ┴ ┴ └─┘ ┴ └─
typ └──────────┘└────────┘└──────┘└─────────────┘┴ └─────────────┘┴ └─────┘┴└┘┴└─┘┴ └─┘ └───────┘┴┴└─
doc └──────────┘ └──────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └─
txt └──────────┘ └──────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └─
par └──────────┘ └──────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └─
pid ┴└──┘└┘ ┴┴└────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴└
st └─────────────────────────────────────────────────────────────────────────────────────────────────
4062
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4063 theorem nodup_cons_of_nodup {a : α} {l : list α} (m : a ∉ l) (n : nodup l) : nodup (a::l) :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ └───┘ ┴└┘┴
src └──┘ ┴ └───┘ └───┘ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ └───┘ ┴└┘┴
doc └───┘ └───┘
4064 nodup_cons.2 ⟨m, n⟩
id └────────┘┴ ┴ ┴
src └────────┘┴
typ └────────┘┴ ┴ ┴
4065
4066 theorem nodup_singleton (a : α) : nodup [a] :=
id ┴ └───┘ ┴┴┴
src └───┘ ┴ ┴
typ ┴ └───┘ ┴┴┴
doc └───┘
4067 nodup_cons_of_nodup (not_mem_nil a) nodup_nil
id └─────────────────┘ └─────────┘ ┴ └───────┘
src └─────────────────┘ └─────────┘ └───────┘
typ └─────────────────┘ └─────────┘ ┴ └───────┘
4068
4069 theorem nodup_of_nodup_cons {a : α} {l : list α} (h : nodup (a::l)) : nodup l :=
id ┴ └──┘ ┴ └───┘ ┴└┘┴ └───┘ ┴
src └──┘ └───┘ └┘ └───┘
typ ┴ └──┘ ┴ └───┘ ┴└┘┴ └───┘ ┴
doc └───┘ └───┘
4070 (nodup_cons.1 h).2
id └────────┘┴ ┴ ┴
src └────────┘┴ ┴
typ └────────┘┴ ┴ ┴
4071
4072 theorem not_mem_of_nodup_cons {a : α} {l : list α} (h : nodup (a::l)) : a ∉ l :=
id ┴ └──┘ ┴ └───┘ ┴└┘┴ ┴ ┴ ┴
src └──┘ └───┘ └┘ ┴
typ ┴ └──┘ ┴ └───┘ ┴└┘┴ ┴ ┴ ┴
doc └───┘
4073 (nodup_cons.1 h).1
id └────────┘┴ ┴ ┴
src └────────┘┴ ┴
typ └────────┘┴ ┴ ┴
4074
4075 theorem not_nodup_cons_of_mem {a : α} {l : list α} : a ∈ l → ¬ nodup (a :: l) :=
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └───┘ ┴ └┘ ┴
src └──┘ ┴ ┴ └───┘ └┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ └───┘ ┴ └┘ ┴
doc └───┘
4076 imp_not_comm.1 not_mem_of_nodup_cons
id └──────────┘┴ └───────────────────┘
src └──────────┘┴ └───────────────────┘
typ └──────────┘┴ └───────────────────┘
4077
4078 theorem nodup_of_sublist {l₁ l₂ : list α} : l₁ <+ l₂ → nodup l₂ → nodup l₁ :=
id └──┘ ┴ └┘ └┘ └┘ └───┘ └┘ └───┘ └┘
src └──┘ └┘ └───┘ └───┘
typ └──┘ ┴ └┘ └┘ └┘ └───┘ └┘ └───┘ └┘
doc └───┘ └───┘
4079 pairwise_of_sublist
id └─────────────────┘
src └─────────────────┘
typ └─────────────────┘
4080
4081 theorem not_nodup_pair (a : α) : ¬ nodup [a, a] :=
id ┴ ┴ └───┘ ┴┴┴ ┴┴
src ┴ └───┘ ┴ ┴ ┴
typ ┴ ┴ └───┘ ┴┴┴ ┴┴
doc └───┘
4082 not_nodup_cons_of_mem $ mem_singleton_self _
id └───────────────────┘ └────────────────┘
src └───────────────────┘ └────────────────┘
typ └───────────────────┘ └────────────────┘
4083
4084 theorem nodup_iff_sublist {l : list α} : nodup l ↔ ∀ a, ¬ [a, a] <+ l :=
id └──┘ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴┴ ┴┴ └┘ ┴
src └──┘ └───┘ ┴ ┴ ┴ ┴ ┴ └┘
typ └──┘ ┴ └───┘ ┴ ┴ ┴ ┴ ┴┴┴ ┴┴ └┘ ┴
doc └───┘
4085 ⟨λ d a h, not_nodup_pair a (nodup_of_sublist h d), begin
id ┴ ┴ ┴ └────────────┘ ┴ └──────────────┘ ┴ ┴
src └────────────┘ └──────────────┘
typ ┴ ┴ ┴ └────────────┘ ┴ └──────────────┘ ┴ ┴
st └─────
4086 induction l with a l IH; intro h, {exact nodup_nil},
id ┴ └───────┘
src └────────┘ └──────────┘ └─────┘ └────┘└───────┘
typ └────────┘┴└──────────┘ └─────┘ └────┘└───────┘
doc └────────┘ └──────────┘ └─────┘ └────┘
txt └────────┘ └──────────┘ └─────┘ └────┘
par └────────┘ └──────────┘ └─────┘ └────┘
pid ┴ ┴└─────────┘ └┘ ┴
st ─────────────────────────────────┘└────────────────┘└┘└
4087 exact nodup_cons_of_nodup
id └─────────────────┘
src └────┘└─────────────────┘└
typ └────┘└─────────────────┘└
doc └────┘ └
txt └────┘ └
par └────┘ └
pid ┴ └
st ────────────────────────────
4088 (λ al, h a $ cons_sublist_cons _ $ singleton_sublist.2 al)
id ┴ └───────────────┘ └───────────────┘
src ───┘ └───┘ ┴ ┴ ┴└───────────────┘└─┘ ┴└───────────────┘└─┘ └─
typ ───┘ └───┘ ┴┴┴ ┴└───────────────┘└─┘ ┴└───────────────┘└─┘ └─
doc ───┘ └───┘ ┴ ┴ ┴ └─┘ ┴ └─┘ └─
txt ───┘ └───┘ ┴ ┴ ┴ └─┘ ┴ └─┘ └─
par ───┘ └───┘ ┴ ┴ ┴ └─┘ ┴ └─┘ └─
pid ───┘ └───┘ ┴ ┴ ┴ └─┘ ┴ └─┘ └─
st ───────────────────────────────────────────────────────────────
4089 (IH $ λ a s, h a $ sublist_cons_of_sublist _ s)
id └┘ ┴ └─────────────────────┘
src ───┘ ┴ ┴ └────┘ ┴ ┴ ┴└─────────────────────┘└─┘ └┘
typ ───┘ └┘┴ ┴ └────┘┴┴ ┴ ┴└─────────────────────┘└─┘ └┘
doc ───┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ └┘
txt ───┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ └┘
par ───┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ └┘
pid ───┘ ┴ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴┴
st ───────────────────────────────────────────────────┘
4090 end⟩
st └─┘
4091
4092 theorem nodup_iff_nth_le_inj {l : list α} :
id └──┘ ┴
src └──┘
typ └──┘ ┴
4093 nodup l ↔ ∀ i j h₁ h₂, nth_le l i h₁ = nth_le l j h₂ → i = j :=
id └───┘ ┴ ┴ ┴ ┴ └┘ └┘ └────┘ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ ┴
src └───┘ ┴ └────┘ ┴ └────┘ ┴
typ └───┘ ┴ ┴ ┴ ┴ └┘ └┘ └────┘ ┴ ┴ └┘ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ ┴
doc └───┘
4094 pairwise_iff_nth_le.trans
id └─────────────────┘└────┘
src └─────────────────┘└────┘
typ └─────────────────┘└────┘
4095 ⟨λ H i j h₁ h₂ h, ((lt_trichotomy _ _)
id ┴ ┴ ┴ └┘ └┘ ┴ └───────────┘
src └───────────┘
typ ┴ ┴ ┴ └┘ └┘ ┴ └───────────┘
4096 .resolve_left (λ h', H _ _ h₂ h' h))
id └──────────┘ └┘ ┴ └┘ └┘ ┴
src └──────────┘
typ └──────────┘ └┘ ┴ └┘ └┘ ┴
4097 .resolve_right (λ h', H _ _ h₁ h' h.symm),
id └───────────┘ └┘ ┴ └┘ └┘ ┴└───┘
src └───────────┘ └───┘
typ └───────────┘ └┘ ┴ └┘ └┘ ┴└───┘
4098 λ H i j h₁ h₂ h, ne_of_lt h₂ (H _ _ _ _ h)⟩
id ┴ ┴ ┴ └┘ └┘ ┴ └──────┘ └┘ ┴ ┴
src └──────┘
typ ┴ ┴ ┴ └┘ └┘ ┴ └──────┘ └┘ ┴ ┴
4099
4100 @[simp] theorem nth_le_index_of [decidable_eq α] {l : list α} (H : nodup l) (n h) : index_of (nth_le l n h) l = n :=
id └──────────┘ ┴ └──┘ ┴ └───┘ ┴ └──────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
src └──────────┘ └──┘ └───┘ └──────┘ └────┘ ┴
typ └──────────┘ ┴ └──┘ ┴ └───┘ ┴ └──────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └───┘
4101 nodup_iff_nth_le_inj.1 H _ _ _ h $
id └──────────────────┘┴ ┴ ┴
src └──────────────────┘┴
typ └──────────────────┘┴ ┴ ┴
4102 index_of_nth_le $ index_of_lt_length.2 $ nth_le_mem _ _ _
id └─────────────┘ └────────────────┘┴ └────────┘
src └─────────────┘ └────────────────┘┴ └────────┘
typ └─────────────┘ └────────────────┘┴ └────────┘
4103
4104 theorem nodup_iff_count_le_one [decidable_eq α] {l : list α} : nodup l ↔ ∀ a, count a l ≤ 1 :=
id └──────────┘ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └──────────┘ └──┘ └───┘ ┴ └───┘ ┴
typ └──────────┘ ┴ └──┘ ┴ └───┘ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc └───┘ └───┘
4105 nodup_iff_sublist.trans $ forall_congr $ λ a,
id └───────────────┘└────┘ └──────────┘ ┴
src └───────────────┘└────┘ └──────────┘
typ └───────────────┘└────┘ └──────────┘ ┴
4106 have [a, a] <+ l ↔ 1 < count a l, from (@le_count_iff_repeat_sublist _ _ a l 2).symm,
id ┴┴┴ ┴┴ └┘ ┴ ┴ ┴ └───┘ ┴ ┴ └─────────────────────────┘ ┴ ┴ └──┘
src ┴ ┴ ┴ └┘ ┴ ┴ └───┘ └─────────────────────────┘ └──┘
typ ┴┴┴ ┴┴ └┘ ┴ ┴ ┴ └───┘ ┴ ┴ └─────────────────────────┘ ┴ ┴ └──┘
doc └───┘
4107 (not_congr this).trans not_lt
id └───────┘ └──┘ └───┘ └────┘
src └───────┘ └───┘ └────┘
typ └───────┘ └──┘ └───┘ └────┘
4108
4109 theorem nodup_repeat (a : α) : ∀ {n : ℕ}, nodup (repeat a n) ↔ n ≤ 1
id ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ ┴ ┴ ┴
src ┴ └───┘ └────┘ ┴ ┴
typ ┴ ┴ ┴ └───┘ └────┘ ┴ ┴ ┴ ┴ ┴
doc └───┘
4110 | 0 := by simp [nat.zero_le]
id └─────────┘
src └────┘└─────────┘└┘
typ └────┘└─────────┘└┘
doc └────┘ └┘
txt └────┘ └┘
par └────┘ └┘
pid ┴┴ ┴┴
st └──────────────────┘
4111 | 1 := by simp
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4112 | (n+2) := iff_of_false
id ┴┴ └──────────┘
src ┴ └──────────┘
typ ┴┴ └──────────┘
4113 (λ H, nodup_iff_sublist.1 H a ((repeat_sublist_repeat _).2 (le_add_left 2 n)))
id ┴ └───────────────┘┴ ┴ ┴ └───────────────────┘ ┴ └─────────┘
src └───────────────┘┴ └───────────────────┘ ┴ └─────────┘
typ ┴ └───────────────┘┴ ┴ ┴ └───────────────────┘ ┴ └─────────┘
4114 (not_le_of_lt $ le_add_left 2 n)
id └──────────┘ └─────────┘
src └──────────┘ └─────────┘
typ └──────────┘ └─────────┘
4115
4116 @[simp] theorem count_eq_one_of_mem [decidable_eq α] {a : α} {l : list α}
id └──────────┘ ┴ ┴ └──┘ ┴
src └──────────┘ └──┘
typ └──────────┘ ┴ ┴ └──┘ ┴
doc └──┘
4117 (d : nodup l) (h : a ∈ l) : count a l = 1 :=
id └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
src └───┘ ┴ └───┘ ┴
typ └───┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ ┴
doc └───┘ └───┘
4118 le_antisymm (nodup_iff_count_le_one.1 d a) (count_pos.2 h)
id └─────────┘ └────────────────────┘┴ ┴ ┴ └───────┘┴ ┴
src └─────────┘ └────────────────────┘┴ └───────┘┴
typ └─────────┘ └────────────────────┘┴ ┴ ┴ └───────┘┴ ┴
4119
4120 theorem nodup_of_nodup_append_left {l₁ l₂ : list α} : nodup (l₁++l₂) → nodup l₁ :=
id └──┘ ┴ └───┘ └┘└┘└┘ └───┘ └┘
src └──┘ └───┘ └┘ └───┘
typ └──┘ ┴ └───┘ └┘└┘└┘ └───┘ └┘
doc └───┘ └───┘
4121 nodup_of_sublist (sublist_append_left l₁ l₂)
id └──────────────┘ └─────────────────┘ └┘ └┘
src └──────────────┘ └─────────────────┘
typ └──────────────┘ └─────────────────┘ └┘ └┘
4122
4123 theorem nodup_of_nodup_append_right {l₁ l₂ : list α} : nodup (l₁++l₂) → nodup l₂ :=
id └──┘ ┴ └───┘ └┘└┘└┘ └───┘ └┘
src └──┘ └───┘ └┘ └───┘
typ └──┘ ┴ └───┘ └┘└┘└┘ └───┘ └┘
doc └───┘ └───┘
4124 nodup_of_sublist (sublist_append_right l₁ l₂)
id └──────────────┘ └──────────────────┘ └┘ └┘
src └──────────────┘ └──────────────────┘
typ └──────────────┘ └──────────────────┘ └┘ └┘
4125
4126 theorem nodup_append {l₁ l₂ : list α} : nodup (l₁++l₂) ↔ nodup l₁ ∧ nodup l₂ ∧ disjoint l₁ l₂ :=
id └──┘ ┴ └───┘ └┘└┘└┘ ┴ └───┘ └┘ ┴ └───┘ └┘ ┴ └──────┘ └┘ └┘
src └──┘ └───┘ └┘ ┴ └───┘ ┴ └───┘ ┴ └──────┘
typ └──┘ ┴ └───┘ └┘└┘└┘ ┴ └───┘ └┘ ┴ └───┘ └┘ ┴ └──────┘ └┘ └┘
doc └───┘ └───┘ └───┘ └──────┘
4127 by simp only [nodup, pairwise_append, disjoint_iff_ne]
id └───┘ └─────────────┘ └─────────────┘
src └─────────┘└───┘└┘└─────────────┘└┘└─────────────┘└─
typ └─────────┘└───┘└┘└─────────────┘└┘└─────────────┘└─
doc └─────────┘└───┘└┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────
4128
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4129 theorem disjoint_of_nodup_append {l₁ l₂ : list α} (d : nodup (l₁++l₂)) : disjoint l₁ l₂ :=
id └──┘ ┴ └───┘ └┘└┘└┘ └──────┘ └┘ └┘
src └──┘ └───┘ └┘ └──────┘
typ └──┘ ┴ └───┘ └┘└┘└┘ └──────┘ └┘ └┘
doc └───┘ └──────┘
4130 (nodup_append.1 d).2.2
id └──────────┘┴ ┴ ┴ ┴
src └──────────┘┴ ┴ ┴
typ └──────────┘┴ ┴ ┴ ┴
4131
4132 theorem nodup_append_of_nodup {l₁ l₂ : list α} (d₁ : nodup l₁) (d₂ : nodup l₂)
id └──┘ ┴ └───┘ └┘ └───┘ └┘
src └──┘ └───┘ └───┘
typ └──┘ ┴ └───┘ └┘ └───┘ └┘
doc └───┘ └───┘
4133 (dj : disjoint l₁ l₂) : nodup (l₁++l₂) :=
id └──────┘ └┘ └┘ └───┘ └┘└┘└┘
src └──────┘ └───┘ └┘
typ └──────┘ └┘ └┘ └───┘ └┘└┘└┘
doc └──────┘ └───┘
4134 nodup_append.2 ⟨d₁, d₂, dj⟩
id └──────────┘┴ └┘ └┘ └┘
src └──────────┘┴
typ └──────────┘┴ └┘ └┘ └┘
4135
4136 theorem nodup_append_comm {l₁ l₂ : list α} : nodup (l₁++l₂) ↔ nodup (l₂++l₁) :=
id └──┘ ┴ └───┘ └┘└┘└┘ ┴ └───┘ └┘└┘└┘
src └──┘ └───┘ └┘ ┴ └───┘ └┘
typ └──┘ ┴ └───┘ └┘└┘└┘ ┴ └───┘ └┘└┘└┘
doc └───┘ └───┘
4137 by simp only [nodup_append, and.left_comm, disjoint_comm]
id └──────────┘ └───────────┘ └───────────┘
src └─────────┘└──────────┘└┘└───────────┘└┘└───────────┘└─
typ └─────────┘└──────────┘└┘└───────────┘└┘└───────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────────────
4138
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4139 theorem nodup_middle {a : α} {l₁ l₂ : list α} : nodup (l₁ ++ a::l₂) ↔ nodup (a::(l₁++l₂)) :=
id ┴ └──┘ ┴ └───┘ └┘ └┘ ┴└┘└┘ ┴ └───┘ ┴└┘ └┘└┘└┘
src └──┘ └───┘ └┘ └┘ ┴ └───┘ └┘ └┘
typ ┴ └──┘ ┴ └───┘ └┘ └┘ ┴└┘└┘ ┴ └───┘ ┴└┘ └┘└┘└┘
doc └───┘ └───┘
4140 by simp only [nodup_append, not_or_distrib, and.left_comm, and_assoc, nodup_cons, mem_append, disjoint_cons_right]
id └──────────┘ └────────────┘ └───────────┘ └───────┘ └────────┘ └────────┘ └─────────────────┘
src └─────────┘└──────────┘└┘└────────────┘└┘└───────────┘└┘└───────┘└┘└────────┘└┘└────────┘└┘└─────────────────┘└─
typ └─────────┘└──────────┘└┘└────────────┘└┘└───────────┘└┘└───────┘└┘└────────┘└┘└────────┘└┘└─────────────────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
4141
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4142 theorem nodup_of_nodup_map (f : α → β) {l : list α} : nodup (map f l) → nodup l :=
id ┴ ┴ └──┘ ┴ └───┘ └─┘ ┴ ┴ └───┘ ┴
src └──┘ └───┘ └─┘ └───┘
typ ┴ ┴ └──┘ ┴ └───┘ └─┘ ┴ ┴ └───┘ ┴
doc └───┘ └───┘
4143 pairwise_of_pairwise_map f $ λ a b, mt $ congr_arg f
id └──────────────────────┘ ┴ ┴ ┴ └┘ └───────┘ ┴
src └──────────────────────┘ └┘ └───────┘
typ └──────────────────────┘ ┴ ┴ ┴ └┘ └───────┘ ┴
4144
4145 theorem nodup_map_on {f : α → β} {l : list α} (H : ∀x∈l, ∀y∈l, f x = f y → x = y)
id ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
4146 (d : nodup l) : nodup (map f l) :=
id └───┘ ┴ └───┘ └─┘ ┴ ┴
src └───┘ └───┘ └─┘
typ └───┘ ┴ └───┘ └─┘ ┴ ┴
doc └───┘ └───┘
4147 pairwise_map_of_pairwise _ (by exact λ a b ⟨ma, mb, n⟩ e, n (H a ma b mb e)) (pairwise.and_mem.1 d)
id └──────────────────────┘ └┘ └┘ ┴ ┴ └──────────────┘┴ ┴
src └──────────────────────┘ └────┘ └────┘ └┘ └┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └──────────────┘┴
typ └──────────────────────┘ └────┘ └────┘└┘└┘└┘└┘┴└───┘ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ └──────────────┘┴ ┴
doc └────┘ └────┘ └┘ └┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
txt └────┘ └────┘ └┘ └┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
par └────┘ └────┘ └┘ └┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
pid ┴ └────┘ └┘ └┘ └───┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴
st └───────────────────────────────────────────┘
4148
4149 theorem nodup_map {f : α → β} {l : list α} (hf : injective f) : nodup l → nodup (map f l) :=
id ┴ ┴ └──┘ ┴ └───────┘ ┴ └───┘ ┴ └───┘ └─┘ ┴ ┴
src └──┘ └───────┘ └───┘ └───┘ └─┘
typ ┴ ┴ └──┘ ┴ └───────┘ ┴ └───┘ ┴ └───┘ └─┘ ┴ ┴
doc └───┘ └───┘
4150 nodup_map_on (assume x _ y _ h, hf h)
id └──────────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴
src └──────────┘
typ └──────────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴
4151
4152 theorem nodup_map_iff {f : α → β} {l : list α} (hf : injective f) : nodup (map f l) ↔ nodup l :=
id ┴ ┴ └──┘ ┴ └───────┘ ┴ └───┘ └─┘ ┴ ┴ ┴ └───┘ ┴
src └──┘ └───────┘ └───┘ └─┘ ┴ └───┘
typ ┴ ┴ └──┘ ┴ └───────┘ ┴ └───┘ └─┘ ┴ ┴ ┴ └───┘ ┴
doc └───┘ └───┘
4153 ⟨nodup_of_nodup_map _, nodup_map hf⟩
id └────────────────┘ └───────┘ └┘
src └────────────────┘ └───────┘
typ └────────────────┘ └───────┘ └┘
4154
4155 @[simp] theorem nodup_attach {l : list α} : nodup (attach l) ↔ nodup l :=
id └──┘ ┴ └───┘ └────┘ ┴ ┴ └───┘ ┴
src └──┘ └───┘ └────┘ ┴ └───┘
typ └──┘ ┴ └───┘ └────┘ ┴ ┴ └───┘ ┴
doc └──┘ └───┘ └────┘ └───┘
4156 ⟨λ h, attach_map_val l ▸ nodup_map (λ a b, subtype.eq) h,
id ┴ └────────────┘ ┴ ┴ └───────┘ ┴ ┴ └────────┘ ┴
src └────────────┘ ┴ └───────┘ └────────┘
typ ┴ └────────────┘ ┴ ┴ └───────┘ ┴ ┴ └────────┘ ┴
4157 λ h, nodup_of_nodup_map subtype.val ((attach_map_val l).symm ▸ h)⟩
id ┴ └────────────────┘ └─────────┘ └────────────┘ ┴ └──┘ ┴ ┴
src └────────────────┘ └─────────┘ └────────────┘ └──┘ ┴
typ ┴ └────────────────┘ └─────────┘ └────────────┘ ┴ └──┘ ┴ ┴
4158
4159 theorem nodup_pmap {p : α → Prop} {f : Π a, p a → β} {l : list α} {H}
id ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘
typ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
4160 (hf : ∀ a ha b hb, f a ha = f b hb → a = b) (h : nodup l) : nodup (pmap f l H) :=
id ┴ └┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └───┘ ┴ └───┘ └──┘ ┴ ┴ ┴
src ┴ ┴ └───┘ └───┘ └──┘
typ ┴ └┘ ┴ └┘ ┴ ┴ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └───┘ ┴ └───┘ └──┘ ┴ ┴ ┴
doc └───┘ └───┘ └──┘
4161 by rw [pmap_eq_map_attach]; exact nodup_map
id └────────────────┘ └───────┘
src └──┘└────────────────┘┴ └────┘└───────┘└
typ └──┘└────────────────┘┴ └────┘└───────┘└
doc └──┘ ┴ └────┘ └
txt └──┘ ┴ └────┘ └
par └──┘ ┴ └────┘ └
pid └┘ ┴ ┴ └
st └─────────────────────┘┴└─────────────────
4162 (λ ⟨a, ha⟩ ⟨b, hb⟩ h, by congr; exact hf a (H _ ha) b (H _ hb) h)
id └┘ ┴ └┘ ┴ ┴ └┘ ┴
src ─┘ └┘ └┘ └─┘ └┘ └───┘ ┴└───┘└──────┘ ┴ ┴ └─┘ └┘ ┴ └─┘ └┘ └─
typ ─┘ └┘ └┘ └─┘ └┘ └───┘ ┴└───┘└──────┘└┘┴┴┴ └─┘└┘└┘┴┴ ┴└─┘└┘└┘┴└─
doc ─┘ └┘ └┘ └─┘ └┘ └───┘ ┴ └──────┘ ┴ ┴ └─┘ └┘ ┴ └─┘ └┘ └─
txt ─┘ └┘ └┘ └─┘ └┘ └───┘ ┴└───┘└──────┘ ┴ ┴ └─┘ └┘ ┴ └─┘ └┘ └─
par ─┘ └┘ └┘ └─┘ └┘ └───┘ ┴└───┘└──────┘ ┴ ┴ └─┘ └┘ ┴ └─┘ └┘ └─
pid ─┘ └┘ └┘ └─┘ └┘ └───┘ └────────────┘ ┴ ┴ └─┘ └┘ ┴ └─┘ └┘ └─
st ─────────────────────────┘└──────────────────────────────────────┘└─
4163 (nodup_attach.2 h)
id └──────────┘ ┴
src ─┘ └──────────┘└─┘ └─
typ ─┘ └──────────┘└─┘┴└─
doc ─┘ └─┘ └─
txt ─┘ └─┘ └─
par ─┘ └─┘ └─
pid ─┘ └─┘ ┴└
st ─────────────────────
4164
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4165 theorem nodup_filter (p : α → Prop) [decidable_pred p] {l} : nodup l → nodup (filter p l) :=
id ┴ └────────────┘ ┴ └───┘ ┴ └───┘ └────┘ ┴ ┴
src └────────────┘ └───┘ └───┘ └────┘
typ ┴ └────────────┘ ┴ └───┘ ┴ └───┘ └────┘ ┴ ┴
doc └───┘ └───┘
4166 pairwise_filter_of_pairwise p
id └─────────────────────────┘ ┴
src └─────────────────────────┘
typ └─────────────────────────┘ ┴
4167
4168 @[simp] theorem nodup_reverse {l : list α} : nodup (reverse l) ↔ nodup l :=
id └──┘ ┴ └───┘ └─────┘ ┴ ┴ └───┘ ┴
src └──┘ └───┘ └─────┘ ┴ └───┘
typ └──┘ ┴ └───┘ └─────┘ ┴ ┴ └───┘ ┴
doc └──┘ └───┘ └───┘
4169 pairwise_reverse.trans $ by simp only [nodup, ne.def, eq_comm]
id └──────────────┘└────┘ └───┘ └────┘ └─────┘
src └──────────────┘└────┘ └─────────┘└───┘└┘└────┘└┘└─────┘└─
typ └──────────────┘└────┘ └─────────┘└───┘└┘└────┘└┘└─────┘└─
doc └─────────┘└───┘└┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └───────────────────────────────────
4170
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4171 theorem nodup_erase_eq_filter [decidable_eq α] (a : α) {l} (d : nodup l) : l.erase a = filter (≠ a) l :=
id └──────────┘ ┴ ┴ └───┘ ┴ ┴└────┘ ┴ ┴ └────┘ ┴ ┴ ┴
src └──────────┘ └───┘ └────┘ ┴ └────┘ ┴
typ └──────────┘ ┴ ┴ └───┘ ┴ ┴└────┘ ┴ ┴ └────┘ ┴ ┴ ┴
doc └───┘
4172 begin
st └─────
4173 induction d with b l m d IH, {refl},
id ┴
src └────────┘ └──────────────┘ └──┘
typ └────────┘┴└──────────────┘ └──┘
doc └────────┘ └──────────────┘ └──┘
txt └────────┘ └──────────────┘ └──┘
par └────────┘ └──────────────┘ └──┘
pid ┴ ┴└─────────────┘
st ────────────────────────────┘└─────┘└┘└
4174 by_cases b = a,
id ┴ ┴ ┴
src └───────┘ ┴┴┴
typ └───────┘┴┴┴┴┴
doc └───────┘ ┴ ┴
txt └───────┘ ┴ ┴
par └───────┘ ┴ ┴
pid ┴ ┴ ┴
st ───────────────┘└─
4175 { subst h, rw [erase_cons_head, filter_cons_of_neg],
id ┴ └─────────────┘ └────────────────┘
src └────┘ └──┘└─────────────┘└┘└────────────────┘┴
typ └────┘┴ └──┘└─────────────┘└┘└────────────────┘┴
doc └────┘ └──┘ └┘ ┴
txt └────┘ └──┘ └┘ ┴
par └────┘ └──┘ └┘ ┴
pid ┴ └┘ └┘ ┴
st ───┘└─────┘└───────────────────┘└──────────────────┘└──
4176 symmetry, rw filter_eq_self, simpa only [ne.def, eq_comm] using m, exact not_not_intro rfl },
id └────────────┘ └────┘ └─────┘ ┴ └───────────┘ └─┘
src └──────┘ └─┘└────────────┘ └──────────┘└────┘└┘└─────┘└──────┘ └────┘└───────────┘┴└─┘┴
typ └──────┘ └─┘└────────────┘ └──────────┘└────┘└┘└─────┘└──────┘┴ └────┘└───────────┘┴└─┘┴
doc └──────┘ └─┘ └──────────┘ └┘ └──────┘ └────┘ ┴ ┴
txt └──────┘ └─┘ └──────────┘ └┘ └──────┘ └────┘ ┴ ┴
par └──────┘ └─┘ └──────────┘ └┘ └──────┘ └────┘ ┴ ┴
pid ┴ ┴└──┘└┘ └┘ ┴┴└────┘ ┴ ┴ ┴
st ───────────┘└─────────────────┘└────────────────────────────────────┘└────────────────────────┘└┘└
4177 { rw [erase_cons_tail _ h, filter_cons_of_pos, IH], exact h }
id └─────────────┘ ┴ └────────────────┘ └┘ ┴
src └──┘└─────────────┘└─┘ └┘└────────────────┘└┘ ┴ └────┘ ┴
typ └──┘└─────────────┘└─┘┴└┘└────────────────┘└┘└┘┴ └────┘┴┴
doc └──┘ └─┘ └┘ └┘ ┴ └────┘ ┴
txt └──┘ └─┘ └┘ └┘ ┴ └────┘ ┴
par └──┘ └─┘ └┘ └┘ ┴ └────┘ ┴
pid └┘ └─┘ └┘ └┘ ┴ ┴ ┴
st ──────────────────────────┘└──────────────────┘└──┘└─────────┘└─
4178 end
st ──┘
4179
4180 theorem nodup_erase_of_nodup [decidable_eq α] (a : α) {l} : nodup l → nodup (l.erase a) :=
id └──────────┘ ┴ ┴ └───┘ ┴ └───┘ ┴└────┘ ┴
src └──────────┘ └───┘ └───┘ └────┘
typ └──────────┘ ┴ ┴ └───┘ ┴ └───┘ ┴└────┘ ┴
doc └───┘ └───┘
4181 nodup_of_sublist (erase_sublist _ _)
id └──────────────┘ └───────────┘
src └──────────────┘ └───────────┘
typ └──────────────┘ └───────────┘
4182
4183 theorem nodup_diff [decidable_eq α] : ∀ {l₁ l₂ : list α} (h : l₁.nodup), (l₁.diff l₂).nodup
id └──────────┘ ┴ ┴ └──┘ ┴ └┘└────┘ └┘└───┘ └┘ └───┘
src └──────────┘ └──┘ └────┘ └───┘ └───┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └┘└────┘ └┘└───┘ └┘ └───┘
doc └────┘ └───┘
4184 | l₁ [] h := h
id └┘ ┴
src └┘
typ └┘ ┴
4185 | l₁ (a::l₂) h := by rw diff_cons; exact nodup_diff (nodup_erase_of_nodup _ h)
id └┘ └───────┘ └────────┘ └──────────────────┘ ┴
src └┘ └─┘└───────┘ └────┘ ┴ └──────────────────┘└─┘ └─
typ └┘ └─┘└───────┘ └────┘└────────┘┴ └──────────────────┘└─┘┴└─
doc └─┘ └────┘ ┴ └─┘ └─
txt └─┘ └────┘ ┴ └─┘ └─
par └─┘ └────┘ ┴ └─┘ └─
pid ┴ ┴ ┴ └─┘ ┴└
st └──────────────────────────────────────────────────────────
4186
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4187 theorem mem_erase_iff_of_nodup [decidable_eq α] {a b : α} {l} (d : nodup l) :
id └──────────┘ ┴ ┴ └───┘ ┴
src └──────────┘ └───┘
typ └──────────┘ ┴ ┴ └───┘ ┴
doc └───┘
4188 a ∈ l.erase b ↔ a ≠ b ∧ a ∈ l :=
id ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴└────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
4189 by rw nodup_erase_eq_filter b d; simp only [mem_filter, and_comm]
id └───────────────────┘ ┴ ┴ └────────┘ └──────┘
src └─┘└───────────────────┘┴ ┴ └─────────┘└────────┘└┘└──────┘└─
typ └─┘└───────────────────┘┴┴┴┴ └─────────┘└────────┘└┘└──────┘└─
doc └─┘ ┴ ┴ └─────────┘ └┘ └─
txt └─┘ ┴ ┴ └─────────┘ └┘ └─
par └─┘ ┴ ┴ └─────────┘ └┘ └─
pid ┴ ┴ ┴ ┴└──┘└┘ └┘ ┴└
st └───────────────────────────────────────────────────────────────
4190
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4191 theorem mem_erase_of_nodup [decidable_eq α] {a : α} {l} (h : nodup l) : a ∉ l.erase a :=
id └──────────┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴└────┘ ┴
src └──────────┘ └───┘ ┴ └────┘
typ └──────────┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴└────┘ ┴
doc └───┘
4192 λ H, ((mem_erase_iff_of_nodup h).1 H).1 rfl
id ┴ └────────────────────┘ ┴ ┴ ┴ ┴ └─┘
src └────────────────────┘ ┴ ┴ └─┘
typ ┴ └────────────────────┘ ┴ ┴ ┴ ┴ └─┘
4193
4194 theorem nodup_join {L : list (list α)} : nodup (join L) ↔ (∀ l ∈ L, nodup l) ∧ pairwise disjoint L :=
id └──┘ └──┘ ┴ └───┘ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └──────┘ └──────┘ ┴
src └──┘ └──┘ └───┘ └──┘ ┴ └───┘ ┴ └──────┘ └──────┘
typ └──┘ └──┘ ┴ └───┘ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ ┴ └──────┘ └──────┘ ┴
doc └───┘ └───┘ └──────┘ └──────┘
4195 by simp only [nodup, pairwise_join, disjoint_left.symm, forall_mem_ne]
id └───┘ └───────────┘ └───────────┘
src └─────────┘└───┘└┘└───────────┘└┘ └┘└───────────┘└─
typ └─────────┘└───┘└┘└───────────┘└┘└────────────────┘└┘└───────────┘└─
doc └─────────┘└───┘└┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────────
4196
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4197 theorem nodup_bind {l₁ : list α} {f : α → list β} : nodup (l₁.bind f) ↔
id └──┘ ┴ ┴ └──┘ ┴ └───┘ └┘└───┘ ┴ ┴
src └──┘ └──┘ └───┘ └───┘ ┴
typ └──┘ ┴ ┴ └──┘ ┴ └───┘ └┘└───┘ ┴ ┴
doc └───┘
4198 (∀ x ∈ l₁, nodup (f x)) ∧ pairwise (λ (a b : α), disjoint (f a) (f b)) l₁ :=
id ┴ └┘ └───┘ ┴ ┴ ┴ └──────┘ ┴ └──────┘ ┴ ┴ ┴ ┴ └┘
src └───┘ ┴ └──────┘ └──────┘
typ ┴ └┘ └───┘ ┴ ┴ ┴ └──────┘ ┴ └──────┘ ┴ ┴ ┴ ┴ └┘
doc └───┘ └──────┘ └──────┘
4199 by simp only [list.bind, nodup_join, pairwise_map, and_comm, and.left_comm, mem_map, exists_imp_distrib, and_imp];
id └───────┘ └────────┘ └──────────┘ └──────┘ └───────────┘ └─────┘ └────────────────┘ └─────┘
src └─────────┘└───────┘└┘└────────┘└┘└──────────┘└┘└──────┘└┘└───────────┘└┘└─────┘└┘└────────────────┘└┘└─────┘┴
typ └─────────┘└───────┘└┘└────────┘└┘└──────────┘└┘└──────┘└┘└───────────┘└┘└─────┘└┘└────────────────┘└┘└─────┘┴
doc └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ ┴
st └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
4200 rw [show (∀ (l : list β) (x : α), f x = l → x ∈ l₁ → nodup l) ↔
id └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └────┘└──┘┴ └─────┘ ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ └┘ └
typ └──┘ ┴ └────┘└──┘┴┴└─────┘ ┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴┴┴ ┴ ┴ ┴ └┘┴└
doc └──┘ ┴ └────┘ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
txt └──┘ ┴ └────┘ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
par └──┘ ┴ └────┘ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
pid └┘ ┴ └────┘ ┴ └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └
st ──────┘└───────────────────────────────────────────────────────────
4201 (∀ (x : α), x ∈ l₁ → nodup (f x)),
id ┴ ┴ └┘ └───┘ ┴
src ───────────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴└───┘┴ ┴ └───
typ ───────────┘ └────┘┴┴ ┴ ┴┴┴└┘┴ ┴└───┘┴ ┴┴ └───
doc ───────────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴└───┘┴ ┴ └───
txt ───────────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
par ───────────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
pid ───────────┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───
st ───────────────────────────────────────────────
4202 from forall_swap.trans $ forall_congr $ λ_, forall_eq']
id └───────────────┘ └──────────┘ └────────┘
src ───────────┘└───────────────┘┴ ┴└──────────┘┴ ┴ └─┘└────────┘└─
typ ───────────┘└───────────────┘┴ ┴└──────────┘┴ ┴ └─┘└────────┘└─
doc ───────────┘ ┴ ┴ ┴ ┴ └─┘ └─
txt ───────────┘ ┴ ┴ ┴ ┴ └─┘ └─
par ───────────┘ ┴ ┴ ┴ ┴ └─┘ └─
pid ───────────┘ ┴ ┴ ┴ ┴ └─┘ ┴└
st ────────────────────────────────────────────────────────────┘┴└
4203
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4204 theorem nodup_product {l₁ : list α} {l₂ : list β} (d₁ : nodup l₁) (d₂ : nodup l₂) :
id └──┘ ┴ └──┘ ┴ └───┘ └┘ └───┘ └┘
src └──┘ └──┘ └───┘ └───┘
typ └──┘ ┴ └──┘ ┴ └───┘ └┘ └───┘ └┘
doc └───┘ └───┘
4205 nodup (product l₁ l₂) :=
id └───┘ └─────┘ └┘ └┘
src └───┘ └─────┘
typ └───┘ └─────┘ └┘ └┘
doc └───┘ └─────┘
4206 nodup_bind.2
id └────────┘┴
src └────────┘┴
typ └────────┘┴
4207 ⟨λ a ma, nodup_map (injective_of_left_inverse (λ b, (rfl : (a,b).2 = b))) d₂,
id ┴ └┘ └───────┘ └───────────────────────┘ ┴ └─┘ ┴┴ ┴ ┴ ┴ ┴ └┘
src └───────┘ └───────────────────────┘ └─┘ ┴ ┴ ┴
typ ┴ └┘ └───────┘ └───────────────────────┘ ┴ └─┘ ┴┴ ┴ ┴ ┴ ┴ └┘
4208 d₁.imp $ λ a₁ a₂ n x h₁ h₂, begin
id └┘└──┘ └┘ └┘ ┴ ┴ └┘ └┘
src └──┘
typ └┘└──┘ └┘ └┘ ┴ ┴ └┘ └┘
st └─────
4209 rcases mem_map.1 h₁ with ⟨b₁, mb₁, rfl⟩,
id └─────┘ └┘
src └─────┘└─────┘└─┘ └──────────────────┘
typ └─────┘└─────┘└─┘└┘└──────────────────┘
doc └─────┘ └─┘ └──────────────────┘
txt └─────┘ └─┘ └──────────────────┘
par └─────┘ └─┘ └──────────────────┘
pid ┴ └─┘ └──────────────────┘
st ──────────────────────────────────────────┘└─
4210 rcases mem_map.1 h₂ with ⟨b₂, mb₂, ⟨⟩⟩,
id └─────┘ └┘
src └─────┘└─────┘└─┘ └─────────────────┘
typ └─────┘└─────┘└─┘└┘└─────────────────┘
doc └─────┘ └─┘ └─────────────────┘
txt └─────┘ └─┘ └─────────────────┘
par └─────┘ └─┘ └─────────────────┘
pid ┴ └─┘ └─────────────────┘
st ─────────────────────────────────────────┘└─
4211 exact n rfl
id ┴ └─┘
src └────┘ ┴└─┘└
typ └────┘┴┴└─┘└
doc └────┘ ┴ └
txt └────┘ ┴ └
par └────┘ ┴ └
pid ┴ ┴ └
st ────────────────
4212 end⟩
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
4213
4214 theorem nodup_sigma {σ : α → Type*} {l₁ : list α} {l₂ : Π a, list (σ a)}
id ┴ └──┘ ┴ ┴ └──┘ ┴ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ ┴ └──┘ ┴ ┴
4215 (d₁ : nodup l₁) (d₂ : ∀ a, nodup (l₂ a)) : nodup (l₁.sigma l₂) :=
id └───┘ └┘ ┴ └───┘ └┘ ┴ └───┘ └┘└────┘ └┘
src └───┘ └───┘ └───┘ └────┘
typ └───┘ └┘ ┴ └───┘ └┘ ┴ └───┘ └┘└────┘ └┘
doc └───┘ └───┘ └───┘ └────┘
4216 nodup_bind.2
id └────────┘┴
src └────────┘┴
typ └────────┘┴
4217 ⟨λ a ma, nodup_map (λ b b' h, by injection h with _ h; exact eq_of_heq h) (d₂ a),
id ┴ └┘ └───────┘ ┴ └┘ ┴ ┴ └───────┘ ┴ └┘ ┴
src └───────┘ └────────┘ └───────┘ └────┘└───────┘┴
typ ┴ └┘ └───────┘ ┴ └┘ ┴ └────────┘┴└───────┘ └────┘└───────┘┴┴ └┘ ┴
doc └────────┘ └───────┘ └────┘ ┴
txt └────────┘ └───────┘ └────┘ ┴
par └────────┘ └───────┘ └────┘ ┴
pid ┴ └───────┘ ┴ ┴
st └──────────────────────────────────────┘
4218 d₁.imp $ λ a₁ a₂ n x h₁ h₂, begin
id └┘└──┘ └┘ └┘ ┴ ┴ └┘ └┘
src └──┘
typ └┘└──┘ └┘ └┘ ┴ ┴ └┘ └┘
st └─────
4219 rcases mem_map.1 h₁ with ⟨b₁, mb₁, rfl⟩,
id └─────┘ └┘
src └─────┘└─────┘└─┘ └──────────────────┘
typ └─────┘└─────┘└─┘└┘└──────────────────┘
doc └─────┘ └─┘ └──────────────────┘
txt └─────┘ └─┘ └──────────────────┘
par └─────┘ └─┘ └──────────────────┘
pid ┴ └─┘ └──────────────────┘
st ──────────────────────────────────────────┘└─
4220 rcases mem_map.1 h₂ with ⟨b₂, mb₂, ⟨⟩⟩,
id └─────┘ └┘
src └─────┘└─────┘└─┘ └─────────────────┘
typ └─────┘└─────┘└─┘└┘└─────────────────┘
doc └─────┘ └─┘ └─────────────────┘
txt └─────┘ └─┘ └─────────────────┘
par └─────┘ └─┘ └─────────────────┘
pid ┴ └─┘ └─────────────────┘
st ─────────────────────────────────────────┘└─
4221 exact n rfl
id ┴ └─┘
src └────┘ ┴└─┘└
typ └────┘┴┴└─┘└
doc └────┘ ┴ └
txt └────┘ ┴ └
par └────┘ ┴ └
pid ┴ ┴ └
st ────────────────
4222 end⟩
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
4223
4224 theorem nodup_filter_map {f : α → option β} {l : list α}
id ┴ └────┘ ┴ └──┘ ┴
src └────┘ └──┘
typ ┴ └────┘ ┴ └──┘ ┴
4225 (H : ∀ (a a' : α) (b : β), b ∈ f a → b ∈ f a' → a = a') :
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘
src ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴ └┘
4226 nodup l → nodup (filter_map f l) :=
id └───┘ ┴ └───┘ └────────┘ ┴ ┴
src └───┘ └───┘ └────────┘
typ └───┘ ┴ └───┘ └────────┘ ┴ ┴
doc └───┘ └───┘
4227 pairwise_filter_map_of_pairwise f $ λ a a' n b bm b' bm' e, n $ H a a' b' (e ▸ bm) bm'
id └─────────────────────────────┘ ┴ ┴ └┘ ┴ ┴ └┘ └┘ └─┘ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ └┘ └─┘
src └─────────────────────────────┘ ┴
typ └─────────────────────────────┘ ┴ ┴ └┘ ┴ ┴ └┘ └┘ └─┘ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ └┘ └─┘
4228
4229 theorem nodup_concat {a : α} {l : list α} (h : a ∉ l) (h' : nodup l) : nodup (concat l a) :=
id ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ └───┘ └────┘ ┴ ┴
src └──┘ ┴ └───┘ └───┘ └────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ └───┘ ┴ └───┘ └────┘ ┴ ┴
doc └───┘ └───┘ └────┘
4230 by rw concat_eq_append; exact nodup_append_of_nodup h' (nodup_singleton _) (disjoint_singleton.2 h)
id └──────────────┘ └───────────────────┘ └┘ └─────────────┘ └────────────────┘ ┴
src └─┘└──────────────┘ └────┘└───────────────────┘┴ ┴ └─────────────┘└──┘ └────────────────┘└─┘ └─
typ └─┘└──────────────┘ └────┘└───────────────────┘┴└┘┴ └─────────────┘└──┘ └────────────────┘└─┘┴└─
doc └─┘ └────┘ ┴ ┴ └──┘ └─┘ └─
txt └─┘ └────┘ ┴ ┴ └──┘ └─┘ └─
par └─┘ └────┘ ┴ ┴ └──┘ └─┘ └─
pid ┴ ┴ ┴ ┴ └──┘ └─┘ ┴└
st └─────────────────────────────────────────────────────────────────────────────────────────────────
4231
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4232 theorem nodup_insert [decidable_eq α] {a : α} {l : list α} (h : nodup l) : nodup (insert a l) :=
id └──────────┘ ┴ ┴ └──┘ ┴ └───┘ ┴ └───┘ └────┘ ┴ ┴
src └──────────┘ └──┘ └───┘ └───┘ └────┘
typ └──────────┘ ┴ ┴ └──┘ ┴ └───┘ ┴ └───┘ └────┘ ┴ ┴
doc └───┘ └───┘
4233 if h' : a ∈ l then by rw [insert_of_mem h']; exact h
id └┘ ┴ ┴ ┴ └───────────┘ └┘ ┴
src └┘ ┴ └──┘└───────────┘┴ ┴ └────┘ ┴
typ └┘ ┴ ┴ ┴ └──┘└───────────┘┴└┘┴ └────┘┴┴
doc └──┘ ┴ ┴ └────┘ ┴
txt └──┘ ┴ ┴ └────┘ ┴
par └──┘ ┴ ┴ └────┘ ┴
pid └┘ ┴ ┴ ┴ ┴
st └───────────────────┘┴└────────┘
4234 else by rw [insert_of_not_mem h', nodup_cons]; split; assumption
id └───────────────┘ └┘ └────────┘
src └──┘└───────────────┘┴ └┘└────────┘┴ └───┘ └──────────
typ └──┘└───────────────┘┴└┘└┘└────────┘┴ └───┘ └──────────
doc └──┘ ┴ └┘ ┴ └───┘ └──────────
txt └──┘ ┴ └┘ ┴ └───┘ └──────────
par └──┘ ┴ └┘ ┴ └───┘ └──────────
pid └┘ ┴ └┘ ┴ └
st └───────────────────────┘└──────────┘┴└───────────────────
4235
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4236 theorem nodup_union [decidable_eq α] (l₁ : list α) {l₂ : list α} (h : nodup l₂) :
id └──────────┘ ┴ └──┘ ┴ └──┘ ┴ └───┘ └┘
src └──────────┘ └──┘ └──┘ └───┘
typ └──────────┘ ┴ └──┘ ┴ └──┘ ┴ └───┘ └┘
doc └───┘
4237 nodup (l₁ ∪ l₂) :=
id └───┘ └┘ ┴ └┘
src └───┘ ┴
typ └───┘ └┘ ┴ └┘
doc └───┘
4238 begin
st └─────
4239 induction l₁ with a l₁ ih generalizing l₂,
id └┘
src └────────┘ └───────────────────────────┘
typ └────────┘└┘└───────────────────────────┘
doc └────────┘ └───────────────────────────┘
txt └────────┘ └───────────────────────────┘
par └────────┘ └───────────────────────────┘
pid ┴ ┴└──────────┘└──────────────┘
st ──────────────────────────────────────────┘└─
4240 { exact h },
id ┴
src └────┘ ┴
typ └────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───┘└──────┘└┘└
4241 apply nodup_insert,
id └──────────┘
src └────┘└──────────┘
typ └────┘└──────────┘
doc └────┘
txt └────┘
par └────┘
pid ┴
st ───────────────────┘└─
4242 exact ih h
id └┘ ┴
src └────┘ ┴ ┴
typ └────┘└┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ────────────┘
4243 end
st └─┘
4244
4245 theorem nodup_inter_of_nodup [decidable_eq α] {l₁ : list α} (l₂) : nodup l₁ → nodup (l₁ ∩ l₂) :=
id └──────────┘ ┴ └──┘ ┴ └───┘ └┘ └───┘ └┘ ┴ └┘
src └──────────┘ └──┘ └───┘ └───┘ ┴
typ └──────────┘ ┴ └──┘ ┴ └───┘ └┘ └───┘ └┘ ┴ └┘
doc └───┘ └───┘
4246 nodup_filter _
id └──────────┘
src └──────────┘
typ └──────────┘
4247
4248 @[simp] theorem nodup_sublists {l : list α} : nodup (sublists l) ↔ nodup l :=
id └──┘ ┴ └───┘ └──────┘ ┴ ┴ └───┘ ┴
src └──┘ └───┘ └──────┘ ┴ └───┘
typ └──┘ ┴ └───┘ └──────┘ ┴ ┴ └───┘ ┴
doc └──┘ └───┘ └──────┘ └───┘
4249 ⟨λ h, nodup_of_nodup_map _ (nodup_of_sublist (map_ret_sublist_sublists _) h),
id ┴ └────────────────┘ └──────────────┘ └──────────────────────┘ ┴
src └────────────────┘ └──────────────┘ └──────────────────────┘
typ ┴ └────────────────┘ └──────────────┘ └──────────────────────┘ ┴
4250 λ h, (pairwise_sublists h).imp (λ _ _ h, mt reverse_inj.2 h.to_ne)⟩
id ┴ └───────────────┘ ┴ └─┘ ┴ ┴ ┴ └┘ └─────────┘┴ ┴└────┘
src └───────────────┘ └─┘ └┘ └─────────┘┴ └────┘
typ ┴ └───────────────┘ ┴ └─┘ ┴ ┴ ┴ └┘ └─────────┘┴ ┴└────┘
4251
4252 @[simp] theorem nodup_sublists' {l : list α} : nodup (sublists' l) ↔ nodup l :=
id └──┘ ┴ └───┘ └───────┘ ┴ ┴ └───┘ ┴
src └──┘ └───┘ └───────┘ ┴ └───┘
typ └──┘ ┴ └───┘ └───────┘ ┴ ┴ └───┘ ┴
doc └──┘ └───┘ └───────┘ └───┘
4253 by rw [sublists'_eq_sublists, nodup_map_iff reverse_injective,
id └───────────────────┘ └───────────┘ └───────────────┘
src └──┘└───────────────────┘└┘└───────────┘┴└───────────────┘└─
typ └──┘└───────────────────┘└┘└───────────┘┴└───────────────┘└─
doc └──┘ └┘ ┴ └─
txt └──┘ └┘ ┴ └─
par └──┘ └┘ ┴ └─
pid └┘ └┘ ┴ └─
st └────────────────────────┘└───────────────────────────────┘└─
4254 nodup_sublists, nodup_reverse]
id └────────────┘ └───────────┘
src ──────┘└────────────┘└┘└───────────┘└─
typ ──────┘└────────────┘└┘└───────────┘└─
doc ──────┘ └┘ └─
txt ──────┘ └┘ └─
par ──────┘ └┘ └─
pid ──────┘ └┘ ┴└
st ────────────────────┘└─────────────┘┴└
4255
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4256 lemma nodup_sublists_len {α : Type*} (n) {l : list α}
id └──┘ ┴
src └──┘
typ └──┘ ┴
4257 (nd : nodup l) : (sublists_len n l).nodup :=
id └───┘ ┴ └──────────┘ ┴ ┴ └───┘
src └───┘ └──────────┘ └───┘
typ └───┘ ┴ └──────────┘ ┴ ┴ └───┘
doc └───┘ └───┘
4258 nodup_of_sublist (sublists_len_sublist_sublists' _ _) (nodup_sublists'.2 nd)
id └──────────────┘ └────────────────────────────┘ └─────────────┘┴ └┘
src └──────────────┘ └────────────────────────────┘ └─────────────┘┴
typ └──────────────┘ └────────────────────────────┘ └─────────────┘┴ └┘
4259
4260 lemma diff_eq_filter_of_nodup [decidable_eq α] :
id └──────────┘ ┴
src └──────────┘
typ └──────────┘ ┴
4261 ∀ {l₁ l₂ : list α} (hl₁ : l₁.nodup), l₁.diff l₂ = l₁.filter (∉ l₂)
id ┴ └──┘ ┴ └┘└────┘ └┘└───┘ └┘ ┴ └┘└─────┘ ┴ └┘
src └──┘ └────┘ └───┘ ┴ └─────┘ ┴
typ ┴ └──┘ ┴ └┘└────┘ └┘└───┘ └┘ ┴ └┘└─────┘ ┴ └┘
doc └────┘
4262 | l₁ [] hl₁ := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4263 | l₁ (a::l₂) hl₁ :=
id └┘
src └┘
typ └┘
4264 begin
st └─────
4265 rw [diff_cons, diff_eq_filter_of_nodup (nodup_erase_of_nodup _ hl₁),
id └───────┘ └─────────────────────┘ └──────────────────┘ └─┘
src └──┘└───────┘└┘ ┴ └──────────────────┘└─┘ └──
typ └──┘└───────┘└┘└─────────────────────┘┴ └──────────────────┘└─┘└─┘└──
doc └──┘ └┘ ┴ └─┘ └──
txt └──┘ └┘ ┴ └─┘ └──
par └──┘ └┘ ┴ └─┘ └──
pid └┘ └┘ ┴ └─┘ └──
st ──────────────┘└────────────────────────────────────────────────────┘└─
4266 nodup_erase_eq_filter _ hl₁, filter_filter],
id └───────────────────┘ └─┘ └───────────┘
src ───┘└───────────────────┘└─┘ └┘└───────────┘┴
typ ───┘└───────────────────┘└─┘└─┘└┘└───────────┘┴
doc ───┘ └─┘ └┘ ┴
txt ───┘ └─┘ └┘ ┴
par ───┘ └─┘ └┘ ┴
pid ───┘ └─┘ └┘ ┴
st ──────────────────────────────┘└─────────────┘└──
4267 simp only [mem_cons_iff, not_or_distrib, and.comm],
id └──────────┘ └────────────┘ └──────┘
src └─────────┘└──────────┘└┘└────────────┘└┘└──────┘┴
typ └─────────┘└──────────┘└┘└────────────┘└┘└──────┘┴
doc └─────────┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ ┴
st ───────────────────────────────────────────────────┘└─
4268 congr
src └────┘
typ └────┘
txt └────┘
par └────┘
pid ┴
st ───────┘
4269 end
st └─┘
4270
4271 lemma mem_diff_iff_of_nodup [decidable_eq α] {l₁ l₂ : list α} (hl₁ : l₁.nodup) {a : α} :
id └──────────┘ ┴ └──┘ ┴ └┘└────┘ ┴
src └──────────┘ └──┘ └────┘
typ └──────────┘ ┴ └──┘ ┴ └┘└────┘ ┴
doc └────┘
4272 a ∈ l₁.diff l₂ ↔ a ∈ l₁ ∧ a ∉ l₂ :=
id ┴ ┴ └┘└───┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
src ┴ └───┘ ┴ ┴ ┴ ┴
typ ┴ ┴ └┘└───┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ └┘
4273 by rw [diff_eq_filter_of_nodup hl₁, mem_filter]
id └─────────────────────┘ └─┘ └────────┘
src └──┘└─────────────────────┘┴ └┘└────────┘└─
typ └──┘└─────────────────────┘┴└─┘└┘└────────┘└─
doc └──┘ ┴ └┘ └─
txt └──┘ ┴ └┘ └─
par └──┘ ┴ └┘ └─
pid └┘ ┴ └┘ ┴└
st └──────────────────────────────┘└──────────┘┴└
4274
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4275 lemma nodup_update_nth : ∀ {l : list α} {n : ℕ} {a : α} (hl : l.nodup) (ha : a ∉ l),
id ┴ └──┘ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴
src └──┘ ┴ └────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴└────┘ ┴ ┴ ┴
doc └────┘
4276 (l.update_nth n a).nodup
id ┴└─────────┘ ┴ ┴ └───┘
src └─────────┘ └───┘
typ ┴└─────────┘ ┴ ┴ └───┘
doc └───┘
4277 | [] n a hl ha := nodup_nil
id └┘ └───────┘
src └┘ └───────┘
typ └┘ └───────┘
4278 | (b::l) 0 a hl ha := nodup_cons.2 ⟨mt (mem_cons_of_mem _) ha, (nodup_cons.1 hl).2⟩
id └┘ └┘ └┘ └────────┘┴ └┘ └─────────────┘ └────────┘┴ ┴
src └┘ └────────┘┴ └┘ └─────────────┘ └────────┘┴ ┴
typ └┘ └┘ └┘ └────────┘┴ └┘ └─────────────┘ └────────┘┴ ┴
4279 | (b::l) (n+1) a hl ha := nodup_cons.2
id └┘ ┴ └┘ └┘ └────────┘┴
src └┘ ┴ └────────┘┴
typ └┘ ┴ └┘ └┘ └────────┘┴
4280 ⟨λ h, (mem_or_eq_of_mem_update_nth h).elim
id ┴ └─────────────────────────┘ ┴ └──┘
src └─────────────────────────┘ └──┘
typ ┴ └─────────────────────────┘ ┴ └──┘
4281 (nodup_cons.1 hl).1
id └────────┘┴ ┴
src └────────┘┴ ┴
typ └────────┘┴ ┴
4282 (λ hba, ha (hba ▸ mem_cons_self _ _)),
id └─┘ └─┘ ┴ └───────────┘
src ┴ └───────────┘
typ └─┘ └─┘ ┴ └───────────┘
4283 nodup_update_nth (nodup_cons.1 hl).2 (mt (mem_cons_of_mem _) ha)⟩
id └──────────────┘ └────────┘┴ ┴ └┘ └─────────────┘
src └────────┘┴ ┴ └┘ └─────────────┘
typ └──────────────┘ └────────┘┴ ┴ └┘ └─────────────┘
4284
4285 end nodup
4286
4287 /- erase duplicates function -/
4288
4289 section erase_dup
4290 variable [decidable_eq α]
id └──────────┘
src └──────────┘
typ └──────────┘
4291
4292 @[simp] theorem erase_dup_nil : erase_dup [] = ([] : list α) := rfl
id └───────┘ └┘ ┴ └┘ └──┘ ┴ └─┘
src └───────┘ └┘ ┴ └┘ └──┘ └─┘
typ └───────┘ └┘ ┴ └┘ └──┘ ┴ └─┘
doc └──┘ └───────┘
4293
4294 theorem erase_dup_cons_of_mem' {a : α} {l : list α} (h : a ∈ erase_dup l) :
id ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴
src └──┘ ┴ └───────┘
typ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴
doc └───────┘
4295 erase_dup (a::l) = erase_dup l :=
id └───────┘ ┴└┘┴ ┴ └───────┘ ┴
src └───────┘ └┘ ┴ └───────┘
typ └───────┘ ┴└┘┴ ┴ └───────┘ ┴
doc └───────┘ └───────┘
4296 pw_filter_cons_of_neg $ by simpa only [forall_mem_ne] using h
id └───────────────────┘ └───────────┘ ┴
src └───────────────────┘ └──────────┘└───────────┘└──────┘ └
typ └───────────────────┘ └──────────┘└───────────┘└──────┘┴└
doc └──────────┘ └──────┘ └
txt └──────────┘ └──────┘ └
par └──────────┘ └──────┘ └
pid ┴└──┘└┘ ┴┴└────┘ └
st └───────────────────────────────────
4297
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4298 theorem erase_dup_cons_of_not_mem' {a : α} {l : list α} (h : a ∉ erase_dup l) :
id ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴
src └──┘ ┴ └───────┘
typ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴
doc └───────┘
4299 erase_dup (a::l) = a :: erase_dup l :=
id └───────┘ ┴└┘┴ ┴ ┴ └┘ └───────┘ ┴
src └───────┘ └┘ ┴ └┘ └───────┘
typ └───────┘ ┴└┘┴ ┴ ┴ └┘ └───────┘ ┴
doc └───────┘ └───────┘
4300 pw_filter_cons_of_pos $ by simpa only [forall_mem_ne] using h
id └───────────────────┘ └───────────┘ ┴
src └───────────────────┘ └──────────┘└───────────┘└──────┘ └
typ └───────────────────┘ └──────────┘└───────────┘└──────┘┴└
doc └──────────┘ └──────┘ └
txt └──────────┘ └──────┘ └
par └──────────┘ └──────┘ └
pid ┴└──┘└┘ ┴┴└────┘ └
st └───────────────────────────────────
4301
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4302 @[simp] theorem mem_erase_dup {a : α} {l : list α} : a ∈ erase_dup l ↔ a ∈ l :=
id ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ └───────┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ └───────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └───────┘
4303 by simpa only [erase_dup, forall_mem_ne, not_not] using not_congr (@forall_mem_pw_filter α (≠) _
id └───────┘ └───────────┘ └─────┘ └───────┘ └──────────────────┘ ┴ ┴
src └──────────┘└───────┘└┘└───────────┘└┘└─────┘└──────┘└───────┘┴ └──────────────────┘┴ ┴┴└────
typ └──────────┘└───────┘└┘└───────────┘└┘└─────┘└──────┘└───────┘┴ └──────────────────┘┴┴┴┴└────
doc └──────────┘└───────┘└┘ └┘ └──────┘ ┴ ┴ ┴ └────
txt └──────────┘ └┘ └┘ └──────┘ ┴ ┴ ┴ └────
par └──────────┘ └┘ └┘ └──────┘ ┴ ┴ ┴ └────
pid ┴└──┘└┘ └┘ └┘ ┴┴└────┘ ┴ ┴ ┴ └────
st └──────────────────────────────────────────────────────────────────────────────────────────────
4304 (λ x y z xz, not_and_distrib.1 $ mt (and.rec eq.trans) xz) a l)
id └─────────────┘ └┘ └─────┘ └──────┘ ┴ ┴
src ─┘ └─────────┘└─────────────┘└─┘ ┴└┘┴ └─────┘┴└──────┘└┘ └┘ ┴ └─
typ ─┘ └─────────┘└─────────────┘└─┘ ┴└┘┴ └─────┘┴└──────┘└┘ └┘┴┴┴└─
doc ─┘ └─────────┘ └─┘ ┴ ┴ ┴ └┘ └┘ ┴ └─
txt ─┘ └─────────┘ └─┘ ┴ ┴ ┴ └┘ └┘ ┴ └─
par ─┘ └─────────┘ └─┘ ┴ ┴ ┴ └┘ └┘ ┴ └─
pid ─┘ └─────────┘ └─┘ ┴ ┴ ┴ └┘ └┘ ┴ ┴└
st ──────────────────────────────────────────────────────────────────
4305
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4306 @[simp] theorem erase_dup_cons_of_mem {a : α} {l : list α} (h : a ∈ l) :
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘
4307 erase_dup (a::l) = erase_dup l :=
id └───────┘ ┴└┘┴ ┴ └───────┘ ┴
src └───────┘ └┘ ┴ └───────┘
typ └───────┘ ┴└┘┴ ┴ └───────┘ ┴
doc └───────┘ └───────┘
4308 erase_dup_cons_of_mem' $ mem_erase_dup.2 h
id └────────────────────┘ └───────────┘┴ ┴
src └────────────────────┘ └───────────┘┴
typ └────────────────────┘ └───────────┘┴ ┴
4309
4310 @[simp] theorem erase_dup_cons_of_not_mem {a : α} {l : list α} (h : a ∉ l) :
id ┴ └──┘ ┴ ┴ ┴ ┴
src └──┘ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴
doc └──┘
4311 erase_dup (a::l) = a :: erase_dup l :=
id └───────┘ ┴└┘┴ ┴ ┴ └┘ └───────┘ ┴
src └───────┘ └┘ ┴ └┘ └───────┘
typ └───────┘ ┴└┘┴ ┴ ┴ └┘ └───────┘ ┴
doc └───────┘ └───────┘
4312 erase_dup_cons_of_not_mem' $ mt mem_erase_dup.1 h
id └────────────────────────┘ └┘ └───────────┘┴ ┴
src └────────────────────────┘ └┘ └───────────┘┴
typ └────────────────────────┘ └┘ └───────────┘┴ ┴
4313
4314 theorem erase_dup_sublist : ∀ (l : list α), erase_dup l <+ l := pw_filter_sublist
id └──┘ ┴ └───────┘ ┴ └┘ ┴ └───────────────┘
src └──┘ └───────┘ └┘ └───────────────┘
typ └──┘ ┴ └───────┘ ┴ └┘ ┴ └───────────────┘
doc └───────┘
4315
4316 theorem erase_dup_subset : ∀ (l : list α), erase_dup l ⊆ l := pw_filter_subset
id └──┘ ┴ └───────┘ ┴ ┴ ┴ └──────────────┘
src └──┘ └───────┘ ┴ └──────────────┘
typ └──┘ ┴ └───────┘ ┴ ┴ ┴ └──────────────┘
doc └───────┘
4317
4318 theorem subset_erase_dup (l : list α) : l ⊆ erase_dup l :=
id └──┘ ┴ ┴ ┴ └───────┘ ┴
src └──┘ ┴ └───────┘
typ └──┘ ┴ ┴ ┴ └───────┘ ┴
doc └───────┘
4319 λ a, mem_erase_dup.2
id ┴ └───────────┘┴
src └───────────┘┴
typ ┴ └───────────┘┴
4320
4321 theorem nodup_erase_dup : ∀ l : list α, nodup (erase_dup l) := pairwise_pw_filter
id └──┘ ┴ └───┘ └───────┘ ┴ └────────────────┘
src └──┘ └───┘ └───────┘ └────────────────┘
typ └──┘ ┴ └───┘ └───────┘ ┴ └────────────────┘
doc └───┘ └───────┘
4322
4323 theorem erase_dup_eq_self {l : list α} : erase_dup l = l ↔ nodup l := pw_filter_eq_self
id └──┘ ┴ └───────┘ ┴ ┴ ┴ ┴ └───┘ ┴ └───────────────┘
src └──┘ └───────┘ ┴ ┴ └───┘ └───────────────┘
typ └──┘ ┴ └───────┘ ┴ ┴ ┴ ┴ └───┘ ┴ └───────────────┘
doc └───────┘ └───┘
4324
4325 @[simp] theorem erase_dup_idempotent {l : list α} : erase_dup (erase_dup l) = erase_dup l :=
id └──┘ ┴ └───────┘ └───────┘ ┴ ┴ └───────┘ ┴
src └──┘ └───────┘ └───────┘ ┴ └───────┘
typ └──┘ ┴ └───────┘ └───────┘ ┴ ┴ └───────┘ ┴
doc └──┘ └───────┘ └───────┘ └───────┘
4326 pw_filter_idempotent
id └──────────────────┘
src └──────────────────┘
typ └──────────────────┘
4327
4328 theorem erase_dup_append (l₁ l₂ : list α) : erase_dup (l₁ ++ l₂) = l₁ ∪ erase_dup l₂ :=
id └──┘ ┴ └───────┘ └┘ └┘ └┘ ┴ └┘ ┴ └───────┘ └┘
src └──┘ └───────┘ └┘ ┴ ┴ └───────┘
typ └──┘ ┴ └───────┘ └┘ └┘ └┘ ┴ └┘ ┴ └───────┘ └┘
doc └───────┘ └───────┘
4329 begin
st └─────
4330 induction l₁ with a l₁ IH, {refl}, rw [cons_union, ← IH],
id └┘ └────────┘ └┘
src └────────┘ └───────────┘ └──┘ └──┘└────────┘└──┘ ┴
typ └────────┘└┘└───────────┘ └──┘ └──┘└────────┘└──┘└┘┴
doc └────────┘ └───────────┘ └──┘ └──┘ └──┘ ┴
txt └────────┘ └───────────┘ └──┘ └──┘ └──┘ ┴
par └────────┘ └───────────┘ └──┘ └──┘ └──┘ ┴
pid ┴ ┴└──────────┘ └┘ └──┘ ┴
st ──────────────────────────┘└─────┘└┘└─────────────┘└────┘┴└─
4331 show erase_dup (a :: (l₁ ++ l₂)) = insert a (erase_dup (l₁ ++ l₂)),
id └┘ ┴ └────┘ ┴ └───────┘ └┘ └┘
src └───┘ ┴ ┴ ┴ ┴└┘┴ └─┘┴┴└────┘┴ ┴ └───────┘┴ ┴ ┴ └┘
typ └───┘ ┴ ┴ ┴ ┴└┘┴ └─┘┴┴└────┘┴┴┴ └───────┘┴ └┘┴ ┴└┘└┘
doc └───┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └───────┘┴ ┴ ┴ └┘
txt └───┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘
par └───┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘
pid └───┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘
st ───────────────────────────────────────────────────────────────────┘└─
4332 by_cases a ∈ erase_dup (l₁ ++ l₂);
id ┴ ┴ └───────┘ └┘ └┘
src └───────┘ ┴┴┴└───────┘┴ ┴ ┴ ┴
typ └───────┘┴┴┴┴└───────┘┴ └┘┴ ┴└┘┴
doc └───────┘ ┴ ┴└───────┘┴ ┴ ┴ ┴
txt └───────┘ ┴ ┴ ┴ ┴ ┴ ┴
par └───────┘ ┴ ┴ ┴ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴ ┴ ┴ ┴
st ─────────────────────────────────────
4333 [ rw [erase_dup_cons_of_mem' h, insert_of_mem h],
id ┴ └────────────────────┘ ┴ └───────────┘ ┴
src ┴ └──┘└────────────────────┘┴ └┘└───────────┘┴ ┴
typ ┴ └──┘└────────────────────┘┴┴└┘└───────────┘┴┴┴
doc └──┘ ┴ └┘ ┴ ┴
txt └──┘ ┴ └┘ ┴ ┴
par └──┘ ┴ └┘ ┴ ┴
pid └┘ ┴ └┘ ┴ ┴
st ───────┘└──────────────────────┘└───────────────┘┴└─
4334 rw [erase_dup_cons_of_not_mem' h, insert_of_not_mem h]]
id └────────────────────────┘ ┴ └───────────────┘ ┴
src └──┘└────────────────────────┘┴ └┘└───────────────┘┴ ┴
typ └──┘└────────────────────────┘┴┴└┘└───────────────┘┴┴┴
doc └──┘ ┴ └┘ ┴ ┴
txt └──┘ ┴ └┘ ┴ ┴
par └──┘ ┴ └┘ ┴ ┴
pid └┘ ┴ └┘ ┴ ┴
st ───────┘└──────────────────────────┘└───────────────────┘┴┴└
4335 end
st ──┘
4336
4337 end erase_dup
4338
4339 /- iota and range(') -/
4340
4341 @[simp] theorem length_range' : ∀ (s n : ℕ), length (range' s n) = n
id ┴ ┴ └────┘ └────┘ ┴ ┴ ┴ ┴
src ┴ └────┘ └────┘ ┴
typ ┴ ┴ └────┘ └────┘ ┴ ┴ ┴ ┴
doc └──┘ └────┘
4342 | s 0 := rfl
id └─┘
src └─┘
typ └─┘
4343 | s (n+1) := congr_arg succ (length_range' _ _)
id ┴ └───────┘ └──┘ └───────────┘
src ┴ └───────┘ └──┘
typ ┴ └───────┘ └──┘ └───────────┘
4344
4345 @[simp] theorem mem_range' {m : ℕ} : ∀ {s n : ℕ}, m ∈ range' s n ↔ s ≤ m ∧ m < s + n
id ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └────┘
4346 | s 0 := (false_iff _).2 $ λ ⟨H1, H2⟩, not_le_of_lt H2 H1
id └───────┘ ┴ ┴└┘ └┘ └──────────┘
src └───────┘ ┴ └──────────┘
typ └───────┘ ┴ ┴└┘ └┘ └──────────┘
4347 | s (succ n) :=
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
4348 have m = s → m < s + n + 1,
id ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴
4349 from λ e, e ▸ lt_succ_of_le (le_add_right _ _),
id ┴ ┴ ┴ └───────────┘ └──────────┘
src ┴ └───────────┘ └──────────┘
typ ┴ ┴ ┴ └───────────┘ └──────────┘
4350 have l : m = s ∨ s + 1 ≤ m ↔ s ≤ m,
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
4351 by simpa only [eq_comm] using (@le_iff_eq_or_lt _ _ s m).symm,
id └─────┘ └─────────────┘ ┴ ┴
src └──────────┘└─────┘└──────┘ └─────────────┘└───┘ ┴ └────┘
typ └──────────┘└─────┘└──────┘ └─────────────┘└───┘┴┴┴└────┘
doc └──────────┘ └──────┘ └───┘ ┴ └────┘
txt └──────────┘ └──────┘ └───┘ ┴ └────┘
par └──────────┘ └──────┘ └───┘ ┴ └────┘
pid ┴└──┘└┘ ┴┴└────┘ └───┘ ┴ └───┘┴
st └─────────────────────────────────────────────────────────┘
4352 (mem_cons_iff _ _ _).trans $ by simp only [mem_range',
id └──────────┘ └───┘
src └──────────┘ └───┘ └─────────┘ └─
typ └──────────┘ └───┘ └─────────┘└────────┘└─
doc └─────────┘ └─
txt └─────────┘ └─
par └─────────┘ └─
pid ┴└──┘└┘ └─
st └───────────────────────
4353 or_and_distrib_left, or_iff_right_of_imp this, l, add_right_comm]; refl
id └─────────────────┘ └─────────────────┘ └──┘ ┴ └────────────┘
src ───┘└─────────────────┘└┘└─────────────────┘┴ └┘ └┘└────────────┘┴ └────
typ ───┘└─────────────────┘└┘└─────────────────┘┴└──┘└┘┴└┘└────────────┘┴ └────
doc ───┘ └┘ ┴ └┘ └┘ ┴ └────
txt ───┘ └┘ ┴ └┘ └┘ ┴ └────
par ───┘ └┘ ┴ └┘ └┘ ┴ └────
pid ───┘ └┘ ┴ └┘ └┘ ┴ └
st ────────────────────────────────────────────────────────────────────────────
4354
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4355 theorem map_add_range' (a) : ∀ s n : ℕ, map ((+) a) (range' s n) = range' (a + s) n
id ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
src ┴ └─┘ ┴ └────┘ ┴ └────┘ ┴
typ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
doc └────┘ └────┘
4356 | s 0 := rfl
id └─┘
src └─┘
typ └─┘
4357 | s (n+1) := congr_arg (cons _) (map_add_range' (s+1) n)
id ┴ ┴┴ └───────┘ └──┘ └────────────┘ ┴
src ┴ └───────┘ └──┘ ┴
typ ┴ ┴┴ └───────┘ └──┘ └────────────┘ ┴
4358
4359 theorem map_sub_range' (a) : ∀ (s n : ℕ) (h : a ≤ s), map (λ x, x - a) (range' s n) = range' (s - a) n
id ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
src ┴ ┴ └─┘ ┴ └────┘ ┴ └────┘ ┴
typ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴
doc └────┘ └────┘
4360 | s 0 _ := rfl
id └─┘
src └─┘
typ └─┘
4361 | s (n+1) h :=
id ┴
src ┴
typ ┴
4362 begin
st └─────
4363 convert congr_arg (cons (s-a)) (map_sub_range' (s+1) n (nat.le_succ_of_le h)),
id └───────┘ └──┘ ┴┴ └────────────┘ ┴┴ ┴ └───────────────┘ ┴
src └──────┘└───────┘┴ └──┘┴ ┴ └─┘ ┴ ┴└─┘ ┴ └───────────────┘┴ └┘
typ └──────┘└───────┘┴ └──┘┴ ┴┴└─┘ └────────────┘┴ ┴┴└─┘┴┴ └───────────────┘┴┴└┘
doc └──────┘ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴ └┘
txt └──────┘ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴ └┘
par └──────┘ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴ └┘
pid ┴ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴ └┘
st ──────────────────────────────────────────────────────────────────────────────┘└─
4364 rw nat.succ_sub h,
id └──────────┘ ┴
src └─┘└──────────┘┴
typ └─┘└──────────┘┴┴
doc └─┘ ┴
txt └─┘ ┴
par └─┘ ┴
pid ┴ ┴
st ──────────────────┘└─
4365 refl,
src └──┘
typ └──┘
doc └──┘
txt └──┘
par └──┘
st ─────┘└─
4366 end
st ──┘
4367
4368 theorem chain_succ_range' : ∀ s n : ℕ, chain (λ a b, b = succ a) s (range' (s+1) n)
id ┴ ┴ └───┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └────┘ ┴┴ ┴
src ┴ └───┘ ┴ └──┘ └────┘ ┴
typ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ └────┘ ┴┴ ┴
doc └───┘ └────┘
4369 | s 0 := chain.nil
id └───────┘
src └───────┘
typ └───────┘
4370 | s (n+1) := (chain_succ_range' (s+1) n).cons rfl
id ┴ ┴┴ └───────────────┘ ┴ └──┘ └─┘
src ┴ ┴ └──┘ └─┘
typ ┴ ┴┴ └───────────────┘ ┴ └──┘ └─┘
4371
4372 theorem chain_lt_range' (s n : ℕ) : chain (<) s (range' (s+1) n) :=
id ┴ └───┘ ┴ ┴ └────┘ ┴┴ ┴
src ┴ └───┘ ┴ └────┘ ┴
typ ┴ └───┘ ┴ ┴ └────┘ ┴┴ ┴
doc └───┘ └────┘
4373 (chain_succ_range' s n).imp (λ a b e, e.symm ▸ lt_succ_self _)
id └───────────────┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴└───┘ ┴ └──────────┘
src └───────────────┘ └─┘ └───┘ ┴ └──────────┘
typ └───────────────┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴└───┘ ┴ └──────────┘
4374
4375 theorem pairwise_lt_range' : ∀ s n : ℕ, pairwise (<) (range' s n)
id ┴ ┴ └──────┘ ┴ └────┘ ┴ ┴
src ┴ └──────┘ ┴ └────┘
typ ┴ ┴ └──────┘ ┴ └────┘ ┴ ┴
doc └──────┘ └────┘
4376 | s 0 := pairwise.nil
id └──────────┘
src └──────────┘
typ └──────────┘
4377 | s (n+1) := (chain_iff_pairwise (by exact λ a b c, lt_trans)).1 (chain_lt_range' s n)
id ┴ ┴┴ └────────────────┘ └──────┘ ┴ └─────────────┘
src ┴ └────────────────┘ └────┘ └──────┘└──────┘ ┴ └─────────────┘
typ ┴ ┴┴ └────────────────┘ └────┘ └──────┘└──────┘ ┴ └─────────────┘
doc └────┘ └──────┘
txt └────┘ └──────┘
par └────┘ └──────┘
pid ┴ └──────┘
st └──────────────────────┘
4378
4379 theorem nodup_range' (s n : ℕ) : nodup (range' s n) :=
id ┴ └───┘ └────┘ ┴ ┴
src ┴ └───┘ └────┘
typ ┴ └───┘ └────┘ ┴ ┴
doc └───┘ └────┘
4380 (pairwise_lt_range' s n).imp (λ a b, ne_of_lt)
id └────────────────┘ ┴ ┴ └─┘ ┴ ┴ └──────┘
src └────────────────┘ └─┘ └──────┘
typ └────────────────┘ ┴ ┴ └─┘ ┴ ┴ └──────┘
4381
4382 @[simp] theorem range'_append : ∀ s m n : ℕ, range' s m ++ range' (s+m) n = range' s (n+m)
id ┴ ┴ └────┘ ┴ ┴ └┘ └────┘ ┴┴┴ ┴ ┴ └────┘ ┴ ┴┴┴
src ┴ └────┘ └┘ └────┘ ┴ ┴ └────┘ ┴
typ ┴ ┴ └────┘ ┴ ┴ └┘ └────┘ ┴┴┴ ┴ ┴ └────┘ ┴ ┴┴┴
doc └──┘ └────┘ └────┘ └────┘
4383 | s 0 n := rfl
id └─┘
src └─┘
typ └─┘
4384 | s (m+1) n := show s :: (range' (s+1) m ++ range' (s+m+1) n) = s :: range' (s+1) (n+m),
id ┴ ┴┴ ┴ └┘ └────┘ ┴ └┘ └────┘ ┴ ┴ ┴ └┘ └────┘ ┴ ┴
src ┴ └┘ └────┘ ┴ └┘ └────┘ ┴ ┴ ┴ └┘ └────┘ ┴ ┴
typ ┴ ┴┴ ┴ └┘ └────┘ ┴ └┘ └────┘ ┴ ┴ ┴ └┘ └────┘ ┴ ┴
doc └────┘ └────┘ └────┘
4385 by rw [add_right_comm, range'_append]
id └────────────┘ └───────────┘
src └──┘└────────────┘└┘ └─
typ └──┘└────────────┘└┘└───────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └─────────────────┘└─────────────┘┴└
4386
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4387 theorem range'_sublist_right {s m n : ℕ} : range' s m <+ range' s n ↔ m ≤ n :=
id ┴ └────┘ ┴ ┴ └┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ └┘ └────┘ ┴ ┴
typ ┴ └────┘ ┴ ┴ └┘ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └────┘ └────┘
4388 ⟨λ h, by simpa only [length_range'] using length_le_of_sublist h,
id ┴ └───────────┘ └──────────────────┘ ┴
src └──────────┘└───────────┘└──────┘└──────────────────┘┴
typ ┴ └──────────┘└───────────┘└──────┘└──────────────────┘┴┴
doc └──────────┘ └──────┘ ┴
txt └──────────┘ └──────┘ ┴
par └──────────┘ └──────┘ ┴
pid ┴└──┘└┘ ┴┴└────┘ ┴
st └──────────────────────────────────────────────────────┘
4389 λ h, by rw [← nat.sub_add_cancel h, ← range'_append]; apply sublist_append_left⟩
id ┴ └────────────────┘ ┴ └───────────┘ └─────────────────┘
src └────┘└────────────────┘┴ └──┘└───────────┘┴ └────┘└─────────────────┘
typ ┴ └────┘└────────────────┘┴┴└──┘└───────────┘┴ └────┘└─────────────────┘
doc └────┘ ┴ └──┘ ┴ └────┘
txt └────┘ ┴ └──┘ ┴ └────┘
par └────┘ ┴ └──┘ ┴ └────┘
pid └──┘ ┴ └──┘ ┴ ┴
st └─────────────────────────┘└───────────────┘┴└─────────────────────────┘
4390
4391 theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤ n :=
id ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ ┴ └────┘ ┴ ┴
typ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └────┘ └────┘
4392 ⟨λ h, le_of_not_lt $ λ hn, lt_irrefl (s+n) $
id ┴ └──────────┘ └┘ └───────┘ ┴┴┴
src └──────────┘ └───────┘ ┴
typ ┴ └──────────┘ └┘ └───────┘ ┴┴┴
4393 (mem_range'.1 $ h $ mem_range'.2 ⟨le_add_right _ _, nat.add_lt_add_left hn s⟩).2,
id └────────┘┴ ┴ └────────┘┴ └──────────┘ └─────────────────┘ └┘ ┴ ┴
src └────────┘┴ └────────┘┴ └──────────┘ └─────────────────┘ ┴
typ └────────┘┴ ┴ └────────┘┴ └──────────┘ └─────────────────┘ └┘ ┴ ┴
4394 λ h, subset_of_sublist (range'_sublist_right.2 h)⟩
id ┴ └───────────────┘ └──────────────────┘┴ ┴
src └───────────────┘ └──────────────────┘┴
typ ┴ └───────────────┘ └──────────────────┘┴ ┴
4395
4396 theorem nth_range' : ∀ s {m n : ℕ}, m < n → nth (range' s n) m = some (s + m)
id ┴ ┴ ┴ ┴ ┴ └─┘ └────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴
src ┴ ┴ └─┘ └────┘ ┴ └──┘ ┴
typ ┴ ┴ ┴ ┴ ┴ └─┘ └────┘ ┴ ┴ ┴ ┴ └──┘ ┴ ┴ ┴
doc └────┘
4397 | s 0 (n+1) _ := rfl
id ┴ └─┘
src ┴ └─┘
typ ┴ └─┘
4398 | s (m+1) (n+1) h := (nth_range' (s+1) (lt_of_add_lt_add_right h)).trans $ by rw add_right_comm; refl
id ┴ ┴ ┴ ┴ └────────┘ ┴ └────────────────────┘ └───┘ └────────────┘
src ┴ ┴ ┴ └────────────────────┘ └───┘ └─┘└────────────┘ └────
typ ┴ ┴ ┴ ┴ └────────┘ ┴ └────────────────────┘ └───┘ └─┘└────────────┘ └────
doc └─┘ └────
txt └─┘ └────
par └─┘ └────
pid ┴ └
st └────────────────────────
4399
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4400 theorem range'_concat (s n : ℕ) : range' s (n + 1) = range' s n ++ [s+n] :=
id ┴ └────┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴┴┴┴┴
src ┴ └────┘ ┴ ┴ └────┘ └┘ ┴ ┴ ┴
typ ┴ └────┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴┴┴┴┴
doc └────┘ └────┘
4401 by rw add_comm n 1; exact (range'_append s n 1).symm
id └──────┘ ┴ └───────────┘ ┴ ┴
src └─┘└──────┘┴ └┘ └────┘ └───────────┘┴ ┴ └────────
typ └─┘└──────┘┴┴└┘ └────┘ └───────────┘┴┴┴┴└────────
doc └─┘ ┴ └┘ └────┘ ┴ ┴ └────────
txt └─┘ ┴ └┘ └────┘ ┴ ┴ └────────
par └─┘ ┴ └┘ └────┘ ┴ ┴ └────────
pid ┴ ┴ ┴┴ ┴ ┴ ┴ └─────┘└─
st └──────────────────────────────────────────────────
4402
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4403 theorem range_core_range' : ∀ s n : ℕ, range_core s (range' s n) = range' 0 (n + s)
id ┴ ┴ └────────┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴
src ┴ └────────┘ └────┘ ┴ └────┘ ┴
typ ┴ ┴ └────────┘ ┴ └────┘ ┴ ┴ ┴ └────┘ ┴ ┴ ┴
doc └────┘ └────┘
4404 | 0 n := rfl
id └─┘
src └─┘
typ └─┘
4405 | (s+1) n := by rw [show n+(s+1) = n+1+s, from add_right_comm n s 1]; exact range_core_range' s (n+1)
id ┴ ┴ ┴ └────────────┘ ┴ ┴ └───────────────┘ ┴ ┴
src ┴ └──┘ ┴ ┴ └─┘┴┴ ┴ └─────┘└────────────┘┴ ┴ └─┘ └────┘ ┴ ┴ └──
typ ┴ └──┘ ┴ ┴ └─┘┴┴ ┴ └─────┘└────────────┘┴┴┴┴└─┘ └────┘└───────────────┘┴┴┴ ┴ └──
doc └──┘ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ └─┘ └────┘ ┴ ┴ └──
txt └──┘ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ └─┘ └────┘ ┴ ┴ └──
par └──┘ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ └─┘ └────┘ ┴ ┴ └──
pid └┘ ┴ └─┘ ┴ ┴ └─────┘ ┴ ┴ └─┘ ┴ ┴ ┴ └┘└
st └─────────────────────────────────────────────────┘└┘└─────────────────────────────────
4406
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4407 theorem range_eq_range' (n : ℕ) : range n = range' 0 n :=
id ┴ └───┘ ┴ ┴ └────┘ ┴
src ┴ └───┘ ┴ └────┘
typ ┴ └───┘ ┴ ┴ └────┘ ┴
doc └────┘
4408 (range_core_range' n 0).trans $ by rw zero_add
id └───────────────┘ ┴ └───┘ └──────┘
src └───────────────┘ └───┘ └─┘└──────┘└
typ └───────────────┘ ┴ └───┘ └─┘└──────┘└
doc └─┘ └
txt └─┘ └
par └─┘ └
pid ┴ └
st └────────────
4409
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4410 theorem range_succ_eq_map (n : ℕ) : range (n + 1) = 0 :: map succ (range n) :=
id ┴ └───┘ ┴ ┴ ┴ └┘ └─┘ └──┘ └───┘ ┴
src ┴ └───┘ ┴ ┴ └┘ └─┘ └──┘ └───┘
typ ┴ └───┘ ┴ ┴ ┴ └┘ └─┘ └──┘ └───┘ ┴
4411 by rw [range_eq_range', range_eq_range', range',
id └─────────────┘ └─────────────┘ └────┘
src └──┘└─────────────┘└┘└─────────────┘└┘└────┘└─
typ └──┘└─────────────┘└┘└─────────────┘└┘└────┘└─
doc └──┘ └┘ └┘└────┘└─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ └─
st └──────────────────┘└───────────────┘└──────┘└─
4412 add_comm, ← map_add_range'];
id └──────┘ └────────────┘
src ──────┘└──────┘└──┘└────────────┘┴
typ ──────┘└──────┘└──┘└────────────┘┴
doc ──────┘ └──┘ ┴
txt ──────┘ └──┘ ┴
par ──────┘ └──┘ ┴
pid ──────┘ └──┘ ┴
st ──────────────┘└────────────────┘┴└─
4413 congr; exact funext one_add
id └────┘ └─────┘
src └───┘ └────┘└────┘┴└─────┘└
typ └───┘ └────┘└────┘┴└─────┘└
doc └────┘ ┴ └
txt └───┘ └────┘ ┴ └
par └───┘ └────┘ ┴ └
pid ┴ ┴ └
st ───────────────────────────────
4414
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4415 theorem range'_eq_map_range (s n : ℕ) : range' s n = map ((+) s) (range n) :=
id ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ └───┘ ┴
src ┴ └────┘ ┴ └─┘ ┴ └───┘
typ ┴ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ └───┘ ┴
doc └────┘
4416 by rw [range_eq_range', map_add_range']; refl
id └─────────────┘ └────────────┘
src └──┘└─────────────┘└┘└────────────┘┴ └────
typ └──┘└─────────────┘└┘└────────────┘┴ └────
doc └──┘ └┘ ┴ └────
txt └──┘ └┘ ┴ └────
par └──┘ └┘ ┴ └────
pid └┘ └┘ ┴ └
st └──────────────────┘└──────────────┘┴└──────
4417
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4418 @[simp] theorem length_range (n : ℕ) : length (range n) = n :=
id ┴ └────┘ └───┘ ┴ ┴ ┴
src ┴ └────┘ └───┘ ┴
typ ┴ └────┘ └───┘ ┴ ┴ ┴
doc └──┘
4419 by simp only [range_eq_range', length_range']
id └─────────────┘ └───────────┘
src └─────────┘└─────────────┘└┘└───────────┘└─
typ └─────────┘└─────────────┘└┘└───────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └───────────────────────────────────────────
4420
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4421 theorem pairwise_lt_range (n : ℕ) : pairwise (<) (range n) :=
id ┴ └──────┘ ┴ └───┘ ┴
src ┴ └──────┘ ┴ └───┘
typ ┴ └──────┘ ┴ └───┘ ┴
doc └──────┘
4422 by simp only [range_eq_range', pairwise_lt_range']
id └─────────────┘ └────────────────┘
src └─────────┘└─────────────┘└┘└────────────────┘└─
typ └─────────┘└─────────────┘└┘└────────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────────────────────────
4423
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4424 theorem nodup_range (n : ℕ) : nodup (range n) :=
id ┴ └───┘ └───┘ ┴
src ┴ └───┘ └───┘
typ ┴ └───┘ └───┘ ┴
doc └───┘
4425 by simp only [range_eq_range', nodup_range']
id └─────────────┘ └──────────┘
src └─────────┘└─────────────┘└┘└──────────┘└─
typ └─────────┘└─────────────┘└┘└──────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └──────────────────────────────────────────
4426
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4427 theorem range_sublist {m n : ℕ} : range m <+ range n ↔ m ≤ n :=
id ┴ └───┘ ┴ └┘ └───┘ ┴ ┴ ┴ ┴ ┴
src ┴ └───┘ └┘ └───┘ ┴ ┴
typ ┴ └───┘ ┴ └┘ └───┘ ┴ ┴ ┴ ┴ ┴
4428 by simp only [range_eq_range', range'_sublist_right]
id └─────────────┘ └──────────────────┘
src └─────────┘└─────────────┘└┘└──────────────────┘└─
typ └─────────┘└─────────────┘└┘└──────────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └──────────────────────────────────────────────────
4429
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4430 theorem range_subset {m n : ℕ} : range m ⊆ range n ↔ m ≤ n :=
id ┴ └───┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
src ┴ └───┘ ┴ └───┘ ┴ ┴
typ ┴ └───┘ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
4431 by simp only [range_eq_range', range'_subset_right]
id └─────────────┘ └─────────────────┘
src └─────────┘└─────────────┘└┘└─────────────────┘└─
typ └─────────┘└─────────────┘└┘└─────────────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └─────────────────────────────────────────────────
4432
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4433 @[simp] theorem mem_range {m n : ℕ} : m ∈ range n ↔ m < n :=
id ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ └───┘ ┴ ┴
typ ┴ ┴ ┴ └───┘ ┴ ┴ ┴ ┴ ┴
doc └──┘
4434 by simp only [range_eq_range', mem_range', nat.zero_le, true_and, zero_add]
id └─────────────┘ └────────┘ └─────────┘ └──────┘ └──────┘
src └─────────┘└─────────────┘└┘└────────┘└┘└─────────┘└┘└──────┘└┘└──────┘└─
typ └─────────┘└─────────────┘└┘└────────┘└┘└─────────┘└┘└──────┘└┘└──────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────────────────
4435
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4436 @[simp] theorem not_mem_range_self {n : ℕ} : n ∉ range n :=
id ┴ ┴ ┴ └───┘ ┴
src ┴ ┴ └───┘
typ ┴ ┴ ┴ └───┘ ┴
doc └──┘
4437 mt mem_range.1 $ lt_irrefl _
id └┘ └───────┘┴ └───────┘
src └┘ └───────┘┴ └───────┘
typ └┘ └───────┘┴ └───────┘
4438
4439 theorem nth_range {m n : ℕ} (h : m < n) : nth (range n) m = some m :=
id ┴ ┴ ┴ ┴ └─┘ └───┘ ┴ ┴ ┴ └──┘ ┴
src ┴ ┴ └─┘ └───┘ ┴ └──┘
typ ┴ ┴ ┴ ┴ └─┘ └───┘ ┴ ┴ ┴ └──┘ ┴
4440 by simp only [range_eq_range', nth_range' _ h, zero_add]
id └─────────────┘ └────────┘ ┴ └──────┘
src └─────────┘└─────────────┘└┘└────────┘└─┘ └┘└──────┘└─
typ └─────────┘└─────────────┘└┘└────────┘└─┘┴└┘└──────┘└─
doc └─────────┘ └┘ └─┘ └┘ └─
txt └─────────┘ └┘ └─┘ └┘ └─
par └─────────┘ └┘ └─┘ └┘ └─
pid ┴└──┘└┘ └┘ └─┘ └┘ ┴└
st └──────────────────────────────────────────────────────
4441
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4442 theorem range_concat (n : ℕ) : range (succ n) = range n ++ [n] :=
id ┴ └───┘ └──┘ ┴ ┴ └───┘ ┴ └┘ ┴┴┴
src ┴ └───┘ └──┘ ┴ └───┘ └┘ ┴ ┴
typ ┴ └───┘ └──┘ ┴ ┴ └───┘ ┴ └┘ ┴┴┴
4443 by simp only [range_eq_range', range'_concat, zero_add]
id └─────────────┘ └───────────┘ └──────┘
src └─────────┘└─────────────┘└┘└───────────┘└┘└──────┘└─
typ └─────────┘└─────────────┘└┘└───────────┘└┘└──────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────
4444
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4445 theorem iota_eq_reverse_range' : ∀ n : ℕ, iota n = reverse (range' 1 n)
id ┴ ┴ └──┘ ┴ ┴ └─────┘ └────┘ ┴
src ┴ └──┘ ┴ └─────┘ └────┘
typ ┴ ┴ └──┘ ┴ ┴ └─────┘ └────┘ ┴
doc └────┘
4446 | 0 := rfl
id └─┘
src └─┘
typ └─┘
4447 | (n+1) := by simp only [iota, range'_concat, iota_eq_reverse_range' n, reverse_append, add_comm]; refl
id ┴ └──┘ └───────────┘ └────────────────────┘ ┴ └────────────┘ └──────┘
src ┴ └─────────┘└──┘└┘└───────────┘└┘ ┴ └┘└────────────┘└┘└──────┘┴ └────
typ ┴ └─────────┘└──┘└┘└───────────┘└┘└────────────────────┘┴┴└┘└────────────┘└┘└──────┘┴ └────
doc └─────────┘ └┘ └┘ ┴ └┘ └┘ ┴ └────
txt └─────────┘ └┘ └┘ ┴ └┘ └┘ ┴ └────
par └─────────┘ └┘ └┘ ┴ └┘ └┘ ┴ └────
pid ┴└──┘└┘ └┘ └┘ ┴ └┘ └┘ ┴ └
st └──────────────────────────────────────────────────────────────────────────────────────────
4448
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4449 @[simp] theorem length_iota (n : ℕ) : length (iota n) = n :=
id ┴ └────┘ └──┘ ┴ ┴ ┴
src ┴ └────┘ └──┘ ┴
typ ┴ └────┘ └──┘ ┴ ┴ ┴
doc └──┘
4450 by simp only [iota_eq_reverse_range', length_reverse, length_range']
id └────────────────────┘ └────────────┘ └───────────┘
src └─────────┘└────────────────────┘└┘└────────────┘└┘└───────────┘└─
typ └─────────┘└────────────────────┘└┘└────────────┘└┘└───────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └──────────────────────────────────────────────────────────────────
4451
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4452 theorem pairwise_gt_iota (n : ℕ) : pairwise (>) (iota n) :=
id ┴ └──────┘ ┴ └──┘ ┴
src ┴ └──────┘ ┴ └──┘
typ ┴ └──────┘ ┴ └──┘ ┴
doc └──────┘
4453 by simp only [iota_eq_reverse_range', pairwise_reverse, pairwise_lt_range']
id └────────────────────┘ └──────────────┘ └────────────────┘
src └─────────┘└────────────────────┘└┘└──────────────┘└┘└────────────────┘└─
typ └─────────┘└────────────────────┘└┘└──────────────┘└┘└────────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────────────────
4454
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4455 theorem nodup_iota (n : ℕ) : nodup (iota n) :=
id ┴ └───┘ └──┘ ┴
src ┴ └───┘ └──┘
typ ┴ └───┘ └──┘ ┴
doc └───┘
4456 by simp only [iota_eq_reverse_range', nodup_reverse, nodup_range']
id └────────────────────┘ └───────────┘ └──────────┘
src └─────────┘└────────────────────┘└┘└───────────┘└┘└──────────┘└─
typ └─────────┘└────────────────────┘└┘└───────────┘└┘└──────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └────────────────────────────────────────────────────────────────
4457
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4458 theorem mem_iota {m n : ℕ} : m ∈ iota n ↔ 1 ≤ m ∧ m ≤ n :=
id ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ └──┘ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
4459 by simp only [iota_eq_reverse_range', mem_reverse, mem_range', add_comm, lt_succ_iff]
id └────────────────────┘ └─────────┘ └────────┘ └──────┘ └─────────┘
src └─────────┘└────────────────────┘└┘└─────────┘└┘└────────┘└┘└──────┘└┘└─────────┘└─
typ └─────────┘└────────────────────┘└┘└─────────┘└┘└────────┘└┘└──────┘└┘└─────────┘└─
doc └─────────┘ └┘ └┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴└
st └───────────────────────────────────────────────────────────────────────────────────
4460
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4461 theorem reverse_range' : ∀ s n : ℕ,
id ┴ ┴
src ┴
typ ┴ ┴
4462 reverse (range' s n) = map (λ i, s + n - 1 - i) (range n)
id └─────┘ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ ┴
src └─────┘ └────┘ ┴ └─┘ ┴ ┴ ┴ └───┘
typ └─────┘ └────┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └───┘ ┴
doc └────┘
4463 | s 0 := rfl
id └─┘
src └─┘
typ └─┘
4464 | s (n+1) := by rw [range'_concat, reverse_append, range_succ_eq_map];
id ┴ └───────────┘ └────────────┘ └───────────────┘
src ┴ └──┘└───────────┘└┘└────────────┘└┘└───────────────┘┴
typ ┴ └──┘└───────────┘└┘└────────────┘└┘└───────────────┘┴
doc └──┘ └┘ └┘ ┴
txt └──┘ └┘ └┘ ┴
par └──┘ └┘ └┘ ┴
pid └┘ └┘ └┘ ┴
st └────────────────┘└──────────────┘└─────────────────┘┴└─
4465 simpa only [show s + (n + 1) - 1 = s + n, from rfl, (∘),
id ┴ ┴ ┴ ┴ ┴ └─┘ ┴
src └──────────┘ ┴ ┴┴┴ ┴ └──┘┴└─┘┴┴ ┴ ┴ └─────┘└─┘└┘┴└───
typ └──────────┘ ┴ ┴┴┴ ┴ └──┘┴└─┘┴┴┴┴ ┴┴└─────┘└─┘└┘┴└───
doc └──────────┘ ┴ ┴ ┴ ┴ └──┘ └─┘ ┴ ┴ ┴ └─────┘ └┘ └───
txt └──────────┘ ┴ ┴ ┴ ┴ └──┘ └─┘ ┴ ┴ ┴ └─────┘ └┘ └───
par └──────────┘ ┴ ┴ ┴ ┴ └──┘ └─┘ ┴ ┴ ┴ └─────┘ └┘ └───
pid ┴└──┘└┘ ┴ ┴ ┴ ┴ └──┘ └─┘ ┴ ┴ ┴ └─────┘ └┘ └───
st ───────────────────────────────────────────────────────────
4466 λ a i, show a - 1 - i = a - succ i, from pred_sub _ _,
id ┴ └──┘ └──────┘
src ───┘ └────┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴└──┘┴ └─────┘└──────┘└─────
typ ───┘ └────┘ ┴ ┴ └─┘ ┴ ┴┴┴ ┴ ┴└──┘┴ └─────┘└──────┘└─────
doc ───┘ └────┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ └─────
txt ───┘ └────┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ └─────
par ───┘ └────┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ └─────
pid ───┘ └────┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └─────┘ └─────
st ───────────────────────────────────────────────────────────
4467 reverse_singleton, map_cons, nat.sub_zero, cons_append,
id └───────────────┘ └──────┘ └──────────┘ └─────────┘
src ───┘└───────────────┘└┘└──────┘└┘└──────────┘└┘└─────────┘└─
typ ───┘└───────────────┘└┘└──────┘└┘└──────────┘└┘└─────────┘└─
doc ───┘ └┘ └┘ └┘ └─
txt ───┘ └┘ └┘ └┘ └─
par ───┘ └┘ └┘ └┘ └─
pid ───┘ └┘ └┘ └┘ └─
st ────────────────────────────────────────────────────────────
4468 nil_append, eq_self_iff_true, true_and, map_map]
id └────────┘ └──────────────┘ └──────┘ └─────┘
src ───┘└────────┘└┘└──────────────┘└┘└──────┘└┘└─────┘└─
typ ───┘└────────┘└┘└──────────────┘└┘└──────┘└┘└─────┘└─
doc ───┘ └┘ └┘ └┘ └─
txt ───┘ └┘ └┘ └┘ └─
par ───┘ └┘ └┘ └┘ └─
pid ───┘ └┘ └┘ └┘ ┴└
st ─────────────────────────────────────────────────────
4469 using reverse_range' s n
id └────────────┘ ┴ ┴
src ───────┘ ┴ ┴ └
typ ───────┘└────────────┘┴┴┴┴└
doc ───────┘ ┴ ┴ └
txt ───────┘ ┴ ┴ └
par ───────┘ ┴ ┴ └
pid ─┘└────┘ ┴ ┴ └
st ───────────────────────────
4470
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4471 /-- All elements of `fin n`, from `0` to `n-1`. -/
4472 def fin_range (n : ℕ) : list (fin n) :=
id ┴ └──┘ └─┘ ┴
src ┴ └──┘ └─┘
typ ┴ └──┘ └─┘ ┴
4473 (range n).pmap fin.mk (λ _, list.mem_range.1)
id └───┘ ┴ └──┘ └────┘ ┴ └────────────┘┴
src └───┘ └──┘ └────┘ └────────────┘┴
typ └───┘ ┴ └──┘ └────┘ ┴ └────────────┘┴
doc └──┘
4474
4475 @[simp] lemma mem_fin_range {n : ℕ} (a : fin n) : a ∈ fin_range n :=
id ┴ └─┘ ┴ ┴ ┴ └───────┘ ┴
src ┴ └─┘ ┴ └───────┘
typ ┴ └─┘ ┴ ┴ ┴ └───────┘ ┴
doc └──┘ └───────┘
4476 mem_pmap.2 ⟨a.1, mem_range.2 a.2, fin.eta _ _⟩
id └──────┘┴ ┴┴ └───────┘┴ ┴┴ └─────┘
src └──────┘┴ ┴ └───────┘┴ ┴ └─────┘
typ └──────┘┴ ┴┴ └───────┘┴ ┴┴ └─────┘
4477
4478 lemma nodup_fin_range (n : ℕ) : (fin_range n).nodup :=
id ┴ └───────┘ ┴ └───┘
src ┴ └───────┘ └───┘
typ ┴ └───────┘ ┴ └───┘
doc └───────┘ └───┘
4479 nodup_pmap (λ _ _ _ _, fin.veq_of_eq) (nodup_range _)
id └────────┘ ┴ ┴ ┴ ┴ └───────────┘ └─────────┘
src └────────┘ └───────────┘ └─────────┘
typ └────────┘ ┴ ┴ ┴ ┴ └───────────┘ └─────────┘
4480
4481 @[simp] lemma length_fin_range (n : ℕ) : (fin_range n).length = n :=
id ┴ └───────┘ ┴ └────┘ ┴ ┴
src ┴ └───────┘ └────┘ ┴
typ ┴ └───────┘ ┴ └────┘ ┴ ┴
doc └──┘ └───────┘
4482 by rw [fin_range, length_pmap, length_range]
id └───────┘ └─────────┘ └──────────┘
src └──┘└───────┘└┘└─────────┘└┘└──────────┘└─
typ └──┘└───────┘└┘└─────────┘└┘└──────────┘└─
doc └──┘└───────┘└┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └────────────┘└───────────┘└────────────┘┴└
4483
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4484 @[to_additive]
doc └─────────┘
4485 theorem prod_range_succ {α : Type u} [monoid α] (f : ℕ → α) (n : ℕ) :
id └────┘ ┴ ┴ ┴ ┴
src └────┘ ┴ ┴
typ └────┘ ┴ ┴ ┴ ┴
4486 ((range n.succ).map f).prod = ((range n).map f).prod * f n :=
id └───┘ ┴└───┘ └─┘ ┴ └──┘ ┴ └───┘ ┴ └─┘ ┴ └──┘ ┴ ┴ ┴
src └───┘ └───┘ └─┘ └──┘ ┴ └───┘ └─┘ └──┘ ┴
typ └───┘ ┴└───┘ └─┘ ┴ └──┘ ┴ └───┘ ┴ └─┘ ┴ └──┘ ┴ ┴ ┴
doc └──┘ └──┘
4487 by rw [range_concat, map_append, map_singleton,
id └──────────┘ └────────┘ └───────────┘
src └──┘└──────────┘└┘└────────┘└┘└───────────┘└─
typ └──┘└──────────┘└┘└────────┘└┘└───────────┘└─
doc └──┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ └─
st └───────────────┘└──────────┘└─────────────┘└─
4488 prod_append, prod_cons, prod_nil, mul_one]
id └─────────┘ └───────┘ └──────┘ └─────┘
src ─┘└─────────┘└┘└───────┘└┘└──────┘└┘└─────┘└─
typ ─┘└─────────┘└┘└───────┘└┘└──────┘└┘└─────┘└─
doc ─┘ └┘ └┘ └┘ └─
txt ─┘ └┘ └┘ └┘ └─
par ─┘ └┘ └┘ └┘ └─
pid ─┘ └┘ └┘ └┘ ┴└
st ────────────┘└─────────┘└────────┘└───────┘┴└
4489
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4490 /--
4491 `Ico n m` is the list of natural numbers `n ≤ x < m`.
4492 (Ico stands for "interval, closed-open".)
4493
4494 See also `data/set/intervals.lean` for `set.Ico`, modelling intervals in general preorders, and
4495 `multiset.Ico` and `finset.Ico` for `n ≤ x < m` as a multiset or as a finset.
4496
4497 @TODO (anyone): Define `Ioo` and `Icc`, state basic lemmas about them.
4498 @TODO (anyone): Prove that `finset.Ico` and `set.Ico` agree.
4499 @TODO (anyone): Also do the versions for integers?
4500 @TODO (anyone): One could generalise even further, defining
4501 'locally finite partial orders', for which `set.Ico a b` is `[finite]`, and
4502 'locally finite total orders', for which there is a list model.
4503 -/
4504 def Ico (n m : ℕ) : list ℕ := range' n (m - n)
id ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴
src ┴ └──┘ ┴ └────┘ ┴
typ ┴ └──┘ ┴ └────┘ ┴ ┴ ┴ ┴
doc └────┘
4505
4506 namespace Ico
4507
4508 theorem zero_bot (n : ℕ) : Ico 0 n = range n :=
id ┴ └─┘ ┴ ┴ └───┘ ┴
src ┴ └─┘ ┴ └───┘
typ ┴ └─┘ ┴ ┴ └───┘ ┴
doc └─┘
4509 by rw [Ico, nat.sub_zero, range_eq_range']
id └─┘ └──────────┘ └─────────────┘
src └──┘└─┘└┘└──────────┘└┘└─────────────┘└─
typ └──┘└─┘└┘└──────────┘└┘└─────────────┘└─
doc └──┘└─┘└┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └──────┘└────────────┘└───────────────┘┴└
4510
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4511 @[simp] theorem length (n m : ℕ) : length (Ico n m) = m - n :=
id ┴ └────┘ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └────┘ └─┘ ┴ ┴
typ ┴ └────┘ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └─┘
4512 by dsimp [Ico]; simp only [length_range']
id └─┘ └───────────┘
src └─────┘└─┘┴ └─────────┘└───────────┘└─
typ └─────┘└─┘┴ └─────────┘└───────────┘└─
doc └─────┘└─┘┴ └─────────┘ └─
txt └─────┘ ┴ └─────────┘ └─
par └─────┘ ┴ └─────────┘ └─
pid ┴┴ ┴ ┴└──┘└┘ ┴└
st └───────────────────────────────────────
4513
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4514 theorem pairwise_lt (n m : ℕ) : pairwise (<) (Ico n m) :=
id ┴ └──────┘ ┴ └─┘ ┴ ┴
src ┴ └──────┘ ┴ └─┘
typ ┴ └──────┘ ┴ └─┘ ┴ ┴
doc └──────┘ └─┘
4515 by dsimp [Ico]; simp only [pairwise_lt_range']
id └─┘ └────────────────┘
src └─────┘└─┘┴ └─────────┘└────────────────┘└─
typ └─────┘└─┘┴ └─────────┘└────────────────┘└─
doc └─────┘└─┘┴ └─────────┘ └─
txt └─────┘ ┴ └─────────┘ └─
par └─────┘ ┴ └─────────┘ └─
pid ┴┴ ┴ ┴└──┘└┘ ┴└
st └────────────────────────────────────────────
4516
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4517 theorem nodup (n m : ℕ) : nodup (Ico n m) :=
id ┴ └───┘ └─┘ ┴ ┴
src ┴ └───┘ └─┘
typ ┴ └───┘ └─┘ ┴ ┴
doc └───┘ └─┘
4518 by dsimp [Ico]; simp only [nodup_range']
id └─┘ └──────────┘
src └─────┘└─┘┴ └─────────┘└──────────┘└─
typ └─────┘└─┘┴ └─────────┘└──────────┘└─
doc └─────┘└─┘┴ └─────────┘ └─
txt └─────┘ ┴ └─────────┘ └─
par └─────┘ ┴ └─────────┘ └─
pid ┴┴ ┴ ┴└──┘└┘ ┴└
st └──────────────────────────────────────
4519
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4520 @[simp] theorem mem {n m l : ℕ} : l ∈ Ico n m ↔ n ≤ l ∧ l < m :=
id ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ └─┘ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴
doc └──┘ └─┘
4521 suffices n ≤ l ∧ l < n + (m - n) ↔ n ≤ l ∧ l < m, by simp [Ico, this],
id ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ └──┘
src ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘└─┘└┘ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘└─┘└┘└──┘┴
doc └────┘└─┘└┘ ┴
txt └────┘ └┘ ┴
par └────┘ └┘ ┴
pid ┴┴ └┘ ┴
st └───────────────┘
4522 begin
st └─────
4523 cases le_total n m with hnm hmn,
id └──────┘ ┴ ┴
src └────┘└──────┘┴ ┴ └───────────┘
typ └────┘└──────┘┴┴┴┴└───────────┘
doc └────┘ ┴ ┴ └───────────┘
txt └────┘ ┴ ┴ └───────────┘
par └────┘ ┴ ┴ └───────────┘
pid ┴ ┴ ┴ └───────────┘
st ────────────────────────────────┘└─
4524 { rw [nat.add_sub_of_le hnm] },
id └───────────────┘ └─┘
src └──┘└───────────────┘┴ └┘
typ └──┘└───────────────┘┴└─┘└┘
doc └──┘ ┴ └┘
txt └──┘ ┴ └┘
par └──┘ ┴ └┘
pid └┘ ┴ ┴┴
st ───┘└───────────────────────┘┴┴└┘└
4525 { rw [nat.sub_eq_zero_of_le hmn, add_zero],
id └───────────────────┘ └─┘ └──────┘
src └──┘└───────────────────┘┴ └┘└──────┘┴
typ └──┘└───────────────────┘┴└─┘└┘└──────┘┴
doc └──┘ ┴ └┘ ┴
txt └──┘ ┴ └┘ ┴
par └──┘ ┴ └┘ ┴
pid └┘ ┴ └┘ ┴
st ────────────────────────────────┘└────────┘┴└─
4526 exact and_congr_right (assume hnl, iff.intro
id └─────────────┘ └───────┘
src └────┘└─────────────┘┴ └────┘└───────┘└
typ └────┘└─────────────┘┴ └────┘└───────┘└
doc └────┘ ┴ └────┘ └
txt └────┘ ┴ └────┘ └
par └────┘ ┴ └────┘ └
pid ┴ ┴ └────┘ └
st ─────────────────────────────────────────────────
4527 (assume hln, (not_le_of_gt hln hnl).elim)
id └──────────┘
src ─────┘ └────┘ └──────────┘┴ ┴ └───────
typ ─────┘ └────┘ └──────────┘┴ ┴ └───────
doc ─────┘ └────┘ ┴ ┴ └───────
txt ─────┘ └────┘ ┴ ┴ └───────
par ─────┘ └────┘ ┴ ┴ └───────
pid ─────┘ └────┘ ┴ ┴ └───────
st ────────────────────────────────────────────────
4528 (assume hlm, lt_of_lt_of_le hlm hmn)) }
id └────────────┘ └─┘
src ─────┘ └────┘└────────────┘┴ ┴ └─┘
typ ─────┘ └────┘└────────────┘┴ ┴└─┘└─┘
doc ─────┘ └────┘ ┴ ┴ └─┘
txt ─────┘ └────┘ ┴ ┴ └─┘
par ─────┘ └────┘ ┴ ┴ └─┘
pid ─────┘ └────┘ ┴ ┴ └┘┴
st ───────────────────────────────────────────┘└─
4529 end
st ──┘
4530
4531 theorem eq_nil_of_le {n m : ℕ} (h : m ≤ n) : Ico n m = [] :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └┘
src ┴ ┴ └─┘ ┴ └┘
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └┘
doc └─┘
4532 by simp [Ico, nat.sub_eq_zero_of_le h]
id └─┘ └───────────────────┘ ┴
src └────┘└─┘└┘└───────────────────┘┴ └─
typ └────┘└─┘└┘└───────────────────┘┴┴└─
doc └────┘└─┘└┘ ┴ └─
txt └────┘ └┘ ┴ └─
par └────┘ └┘ ┴ └─
pid ┴┴ └┘ ┴ ┴└
st └────────────────────────────────────
4533
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4534 theorem map_add (n m k : ℕ) : (Ico n m).map ((+) k) = Ico (n + k) (m + k) :=
id ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ └─┘ └─┘ ┴ ┴ └─┘ ┴ ┴
typ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └─┘ └─┘
4535 by rw [Ico, Ico, map_add_range', nat.add_sub_add_right, add_comm n k]
id └─┘ └─┘ └────────────┘ └───────────────────┘ └──────┘ ┴ ┴
src └──┘└─┘└┘└─┘└┘└────────────┘└┘└───────────────────┘└┘└──────┘┴ ┴ └─
typ └──┘└─┘└┘└─┘└┘└────────────┘└┘└───────────────────┘└┘└──────┘┴┴┴┴└─
doc └──┘└─┘└┘└─┘└┘ └┘ └┘ ┴ ┴ └─
txt └──┘ └┘ └┘ └┘ └┘ ┴ ┴ └─
par └──┘ └┘ └┘ └┘ └┘ ┴ ┴ └─
pid └┘ └┘ └┘ └┘ └┘ ┴ ┴ ┴└
st └──────┘└───┘└──────────────┘└─────────────────────┘└────────────┘┴└
4536
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4537 theorem map_sub (n m k : ℕ) (h₁ : k ≤ n) : (Ico n m).map (λ x, x - k) = Ico (n - k) (m - k) :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ └─┘ └─┘ ┴ ┴ └─┘ ┴ ┴
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴ ┴
doc └─┘ └─┘
4538 begin
st └─────
4539 by_cases h₂ : n < m,
id ┴ ┴ ┴
src └───────┘ └─┘ ┴┴┴
typ └───────┘ └─┘┴┴┴┴┴
doc └───────┘ └─┘ ┴ ┴
txt └───────┘ └─┘ ┴ ┴
par └───────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ────────────────────┘└─
4540 { rw [Ico, Ico],
id └─┘ └─┘
src └──┘└─┘└┘└─┘┴
typ └──┘└─┘└┘└─┘┴
doc └──┘└─┘└┘└─┘┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ───┘└─────┘└───┘└──
4541 rw nat.sub_sub_sub_cancel_right h₁,
id └──────────────────────────┘ └┘
src └─┘└──────────────────────────┘┴
typ └─┘└──────────────────────────┘┴└┘
doc └─┘ ┴
txt └─┘ ┴
par └─┘ ┴
pid ┴ ┴
st ─────────────────────────────────────┘└─
4542 rw [map_sub_range' _ _ _ h₁] },
id └────────────┘ └┘
src └──┘└────────────┘└─────┘ └┘
typ └──┘└────────────┘└─────┘└┘└┘
doc └──┘ └─────┘ └┘
txt └──┘ └─────┘ └┘
par └──┘ └─────┘ └┘
pid └┘ └─────┘ ┴┴
st ──────────────────────────────┘┴┴└┘└
4543 { simp at h₂,
src └────────┘
typ └────────┘
doc └────────┘
txt └────────┘
par └────────┘
pid ┴└───┘
st ─────────────┘└─
4544 rw [eq_nil_of_le h₂],
id └──────────┘ └┘
src └──┘└──────────┘┴ ┴
typ └──┘└──────────┘┴└┘┴
doc └──┘ ┴ ┴
txt └──┘ ┴ ┴
par └──┘ ┴ ┴
pid └┘ ┴ ┴
st ──────────────────────┘└──
4545 rw [eq_nil_of_le (nat.sub_le_sub_right h₂ _)],
id └──────────┘ └──────────────────┘ └┘
src └──┘└──────────┘┴ └──────────────────┘┴ └──┘
typ └──┘└──────────┘┴ └──────────────────┘┴└┘└──┘
doc └──┘ ┴ ┴ └──┘
txt └──┘ ┴ ┴ └──┘
par └──┘ ┴ ┴ └──┘
pid └┘ ┴ ┴ └──┘
st ───────────────────────────────────────────────┘└──
4546 refl }
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st ────────┘└─
4547 end
st ──┘
4548
4549 @[simp] theorem self_empty {n : ℕ} : Ico n n = [] :=
id ┴ └─┘ ┴ ┴ ┴ └┘
src ┴ └─┘ ┴ └┘
typ ┴ └─┘ ┴ ┴ ┴ └┘
doc └──┘ └─┘
4550 eq_nil_of_le (le_refl n)
id └──────────┘ └─────┘ ┴
src └──────────┘ └─────┘
typ └──────────┘ └─────┘ ┴
4551
4552 @[simp] theorem eq_empty_iff {n m : ℕ} : Ico n m = [] ↔ m ≤ n :=
id ┴ └─┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴
src ┴ └─┘ ┴ └┘ ┴ ┴
typ ┴ └─┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴ ┴
doc └──┘ └─┘
4553 iff.intro (assume h, nat.le_of_sub_eq_zero $ by rw [← length, h]; refl) eq_nil_of_le
id └───────┘ ┴ └───────────────────┘ └────┘ ┴ └──────────┘
src └───────┘ └───────────────────┘ └────┘└────┘└┘ ┴ └──┘ └──────────┘
typ └───────┘ ┴ └───────────────────┘ └────┘└────┘└┘┴┴ └──┘ └──────────┘
doc └────┘ └┘ ┴ └──┘
txt └────┘ └┘ ┴ └──┘
par └────┘ └┘ ┴ └──┘
pid └──┘ └┘ ┴
st └───────────┘└─┘┴└────┘
4554
4555 lemma append_consecutive {n m l : ℕ} (hnm : n ≤ m) (hml : m ≤ l) :
id ┴ ┴ ┴ ┴ ┴ ┴ ┴
src ┴ ┴ ┴
typ ┴ ┴ ┴ ┴ ┴ ┴ ┴
4556 Ico n m ++ Ico m l = Ico n l :=
id └─┘ ┴ ┴ └┘ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
src └─┘ └┘ └─┘ ┴ └─┘
typ └─┘ ┴ ┴ └┘ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴
doc └─┘ └─┘ └─┘
4557 begin
st └─────
4558 dunfold Ico,
src └─────────┘
typ └─────────┘
doc └─────────┘
txt └─────────┘
par └─────────┘
pid └──┘
st ────────────┘└─
4559 convert range'_append _ _ _,
id └───────────┘
src └──────┘└───────────┘└────┘
typ └──────┘└───────────┘└────┘
doc └──────┘ └────┘
txt └──────┘ └────┘
par └──────┘ └────┘
pid ┴ └────┘
st ────────────────────────────┘└─
4560 { exact (nat.add_sub_of_le hnm).symm },
id └───────────────┘ └─┘
src └────┘ └───────────────┘┴ └─────┘
typ └────┘ └───────────────┘┴└─┘└─────┘
doc └────┘ ┴ └─────┘
txt └────┘ ┴ └─────┘
par └────┘ ┴ └─────┘
pid ┴ ┴ └───┘└┘
st ───┘└─────────────────────────────────┘└┘└
4561 { rwa [← nat.add_sub_assoc hnm, nat.sub_add_cancel] }
id └───────────────┘ └─┘ └────────────────┘
src └─────┘└───────────────┘┴ └┘└────────────────┘└┘
typ └─────┘└───────────────┘┴└─┘└┘└────────────────┘└┘
doc └─────┘ ┴ └┘ └┘
txt └─────┘ ┴ └┘ └┘
par └─────┘ ┴ └┘ └┘
pid └──┘ ┴ └┘ ┴┴
st ───────────────────────────────┘└──────────────────┘┴┴└─
4562 end
st ──┘
4563
4564 @[simp] lemma inter_consecutive (n m l : ℕ) : Ico n m ∩ Ico m l = [] :=
id ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └┘
src ┴ └─┘ ┴ └─┘ ┴ └┘
typ ┴ └─┘ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ └┘
doc └──┘ └─┘ └─┘
4565 begin
st └─────
4566 apply eq_nil_iff_forall_not_mem.2,
id └───────────────────────┘
src └────┘└───────────────────────┘└┘
typ └────┘└───────────────────────┘└┘
doc └────┘ └┘
txt └────┘ └┘
par └────┘ └┘
pid ┴ └┘
st ──────────────────────────────────┘└─
4567 intro a,
src └─────┘
typ └─────┘
doc └─────┘
txt └─────┘
par └─────┘
pid └┘
st ────────┘└─
4568 simp only [and_imp, not_and, not_lt, list.mem_inter, list.Ico.mem],
id └─────┘ └─────┘ └────┘ └────────────┘ └──────────┘
src └─────────┘└─────┘└┘└─────┘└┘└────┘└┘└────────────┘└┘└──────────┘┴
typ └─────────┘└─────┘└┘└─────┘└┘└────┘└┘└────────────┘└┘└──────────┘┴
doc └─────────┘ └┘ └┘ └┘ └┘ ┴
txt └─────────┘ └┘ └┘ └┘ └┘ ┴
par └─────────┘ └┘ └┘ └┘ └┘ ┴
pid ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴
st ───────────────────────────────────────────────────────────────────┘└─
4569 intros h₁ h₂ h₃,
src └─────────────┘
typ └─────────────┘
doc └─────────────┘
txt └─────────────┘
par └─────────────┘
pid └───────┘
st ────────────────┘└─
4570 exfalso,
src └─────┘
typ └─────┘
doc └─────┘
txt └─────┘
par └─────┘
st ────────┘└─
4571 exact not_lt_of_ge h₃ h₂
id └──────────┘ └┘ └┘
src └────┘└──────────┘┴ ┴ ┴
typ └────┘└──────────┘┴└┘┴└┘┴
doc └────┘ ┴ ┴ ┴
txt └────┘ ┴ ┴ ┴
par └────┘ ┴ ┴ ┴
pid ┴ ┴ ┴ ┴
st ──────────────────────────┘
4572 end
st └─┘
4573
4574 @[simp] lemma bag_inter_consecutive (n m l : ℕ) : list.bag_inter (Ico n m) (Ico m l) = [] :=
id ┴ └────────────┘ └─┘ ┴ ┴ └─┘ ┴ ┴ ┴ └┘
src ┴ └────────────┘ └─┘ └─┘ ┴ └┘
typ ┴ └────────────┘ └─┘ ┴ ┴ └─┘ ┴ ┴ ┴ └┘
doc └──┘ └─┘ └─┘
4575 (bag_inter_nil_iff_inter_nil _ _).2 (inter_consecutive n m l)
id └─────────────────────────┘ ┴ └───────────────┘ ┴ ┴ ┴
src └─────────────────────────┘ ┴ └───────────────┘
typ └─────────────────────────┘ ┴ └───────────────┘ ┴ ┴ ┴
4576
4577 @[simp] theorem succ_singleton {n : ℕ} : Ico n (n+1) = [n] :=
id ┴ └─┘ ┴ ┴┴ ┴ ┴┴┴
src ┴ └─┘ ┴ ┴ ┴ ┴
typ ┴ └─┘ ┴ ┴┴ ┴ ┴┴┴
doc └──┘ └─┘
4578 by dsimp [Ico]; simp [nat.add_sub_cancel_left]
id └─┘ └─────────────────────┘
src └─────┘└─┘┴ └────┘└─────────────────────┘└─
typ └─────┘└─┘┴ └────┘└─────────────────────┘└─
doc └─────┘└─┘┴ └────┘ └─
txt └─────┘ ┴ └────┘ └─
par └─────┘ ┴ └────┘ └─
pid ┴┴ ┴ ┴┴ ┴└
st └────────────────────────────────────────────
4579
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4580 theorem succ_top {n m : ℕ} (h : n ≤ m) : Ico n (m + 1) = Ico n m ++ [m] :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └┘ ┴┴┴
src ┴ ┴ └─┘ ┴ ┴ └─┘ └┘ ┴ ┴
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └┘ ┴┴┴
doc └─┘ └─┘
4581 by rwa [← succ_singleton, append_consecutive]; exact nat.le_succ _
id └────────────┘ └────────────────┘ └─────────┘
src └─────┘└────────────┘└┘└────────────────┘┴ └────┘└─────────┘└──
typ └─────┘└────────────┘└┘└────────────────┘┴ └────┘└─────────┘└──
doc └─────┘ └┘ ┴ └────┘ └──
txt └─────┘ └┘ ┴ └────┘ └──
par └─────┘ └┘ ┴ └────┘ └──
pid └──┘ └┘ ┴ ┴ └┘└
st └────────────────────┘└──────────────────┘┴└─────────────────────
4582
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4583 theorem eq_cons {n m : ℕ} (h : n < m) : Ico n m = n :: Ico (n + 1) m :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ ┴
src ┴ ┴ └─┘ ┴ └┘ └─┘ ┴
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ └┘ └─┘ ┴ ┴ ┴
doc └─┘ └─┘
4584 by rw [← append_consecutive (nat.le_succ n) h, succ_singleton]; refl
id └────────────────┘ └─────────┘ ┴ ┴ └────────────┘
src └────┘└────────────────┘┴ └─────────┘┴ └┘ └┘└────────────┘┴ └────
typ └────┘└────────────────┘┴ └─────────┘┴┴└┘┴└┘└────────────┘┴ └────
doc └────┘ ┴ ┴ └┘ └┘ ┴ └────
txt └────┘ ┴ ┴ └┘ └┘ ┴ └────
par └────┘ ┴ ┴ └┘ └┘ ┴ └────
pid └──┘ ┴ ┴ └┘ └┘ ┴ └
st └─────────────────────────────────────────┘└──────────────┘┴└──────
4585
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4586 @[simp] theorem pred_singleton {m : ℕ} (h : 0 < m) : Ico (m - 1) m = [m - 1] :=
id ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
src ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ └─┘ ┴ ┴ ┴ ┴ ┴┴ ┴ ┴
doc └──┘ └─┘
4587 by dsimp [Ico]; rw nat.sub_sub_self h; simp
id └─┘ └──────────────┘ ┴
src └─────┘└─┘┴ └─┘└──────────────┘┴ └────
typ └─────┘└─┘┴ └─┘└──────────────┘┴┴ └────
doc └─────┘└─┘┴ └─┘ ┴ └────
txt └─────┘ ┴ └─┘ ┴ └────
par └─────┘ ┴ └─┘ ┴ └────
pid ┴┴ ┴ ┴ ┴ └
st └───────────────┘└──────────────┘└────────
4588
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4589 theorem chain'_succ (n m : ℕ) : chain' (λa b, b = succ a) (Ico n m) :=
id ┴ └────┘ ┴ ┴ ┴ ┴ └──┘ ┴ └─┘ ┴ ┴
src ┴ └────┘ ┴ └──┘ └─┘
typ ┴ └────┘ ┴ ┴ ┴ ┴ └──┘ ┴ └─┘ ┴ ┴
doc └────┘ └─┘
4590 begin
st └─────
4591 by_cases n < m,
id ┴ ┴ ┴
src └───────┘ ┴┴┴
typ └───────┘┴┴┴┴┴
doc └───────┘ ┴ ┴
txt └───────┘ ┴ ┴
par └───────┘ ┴ ┴
pid ┴ ┴ ┴
st ───────────────┘└─
4592 { rw [eq_cons h], exact chain_succ_range' _ _ },
id └─────┘ ┴ └───────────────┘
src └──┘└─────┘┴ ┴ └────┘└───────────────┘└───┘
typ └──┘└─────┘┴┴┴ └────┘└───────────────┘└───┘
doc └──┘ ┴ ┴ └────┘ └───┘
txt └──┘ ┴ ┴ └────┘ └───┘
par └──┘ ┴ ┴ └────┘ └───┘
pid └┘ ┴ ┴ ┴ └──┘┴
st ───┘└───────────┘└─────────────────────────────┘└┘└
4593 { rw [eq_nil_of_le (le_of_not_gt h)], trivial }
id └──────────┘ └──────────┘ ┴
src └──┘└──────────┘┴ └──────────┘┴ └┘ └──────┘
typ └──┘└──────────┘┴ └──────────┘┴┴└┘ └──────┘
doc └──┘ ┴ ┴ └┘ └──────┘
txt └──┘ ┴ ┴ └┘ └──────┘
par └──┘ ┴ ┴ └┘ └──────┘
pid └┘ ┴ ┴ └┘ ┴
st ────────────────────────────────────┘└─────────┘└─
4594 end
st ──┘
4595
4596 @[simp] theorem not_mem_top {n m : ℕ} : m ∉ Ico n m :=
id ┴ ┴ ┴ └─┘ ┴ ┴
src ┴ ┴ └─┘
typ ┴ ┴ ┴ └─┘ ┴ ┴
doc └──┘ └─┘
4597 by simp; intros; refl
src └──┘ └────┘ └────
typ └──┘ └────┘ └────
doc └──┘ └────┘ └────
txt └──┘ └────┘ └────
par └──┘ └────┘ └────
pid └
st └───────────────────
4598
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4599 lemma filter_lt_of_top_le {n m l : ℕ} (hml : m ≤ l) : (Ico n m).filter (λ x, x < l) = Ico n m :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src ┴ ┴ └─┘ └────┘ ┴ ┴ └─┘
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
doc └─┘ └─┘
4600 filter_eq_self.2 $ assume k hk, lt_of_lt_of_le (mem.1 hk).2 hml
id └────────────┘┴ ┴ └┘ └────────────┘ └─┘┴ └┘ ┴ └─┘
src └────────────┘┴ └────────────┘ └─┘┴ ┴
typ └────────────┘┴ ┴ └┘ └────────────┘ └─┘┴ └┘ ┴ └─┘
4601
4602 lemma filter_lt_of_le_bot {n m l : ℕ} (hln : l ≤ n) : (Ico n m).filter (λ x, x < l) = [] :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
src ┴ ┴ └─┘ └────┘ ┴ ┴ └┘
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
doc └─┘
4603 filter_eq_nil.2 $ assume k hk, not_lt_of_le $ le_trans hln $ (mem.1 hk).1
id └───────────┘┴ ┴ └┘ └──────────┘ └──────┘ └─┘ └─┘┴ └┘ ┴
src └───────────┘┴ └──────────┘ └──────┘ └─┘┴ ┴
typ └───────────┘┴ ┴ └┘ └──────────┘ └──────┘ └─┘ └─┘┴ └┘ ┴
4604
4605 lemma filter_lt_of_ge {n m l : ℕ} (hlm : l ≤ m) : (Ico n m).filter (λ x, x < l) = Ico n l :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src ┴ ┴ └─┘ └────┘ ┴ ┴ └─┘
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
doc └─┘ └─┘
4606 begin
st └─────
4607 cases le_total n l with hnl hln,
id └──────┘ ┴ ┴
src └────┘└──────┘┴ ┴ └───────────┘
typ └────┘└──────┘┴┴┴┴└───────────┘
doc └────┘ ┴ ┴ └───────────┘
txt └────┘ ┴ ┴ └───────────┘
par └────┘ ┴ ┴ └───────────┘
pid ┴ ┴ ┴ └───────────┘
st ────────────────────────────────┘└─
4608 { rw [← append_consecutive hnl hlm, filter_append,
id └────────────────┘ └─┘ └─┘ └───────────┘
src └────┘└────────────────┘┴ ┴ └┘└───────────┘└─
typ └────┘└────────────────┘┴└─┘┴└─┘└┘└───────────┘└─
doc └────┘ ┴ ┴ └┘ └─
txt └────┘ ┴ ┴ └┘ └─
par └────┘ ┴ ┴ └┘ └─
pid └──┘ ┴ ┴ └┘ └─
st ───┘└──────────────────────────────┘└─────────────┘└─
4609 filter_lt_of_top_le (le_refl l), filter_lt_of_le_bot (le_refl l), append_nil] },
id └─────────────────┘ └─────┘ ┴ └─────────────────┘ └─────┘ ┴ └────────┘
src ─────┘└─────────────────┘┴ └─────┘┴ └─┘└─────────────────┘┴ └─────┘┴ └─┘└────────┘└┘
typ ─────┘└─────────────────┘┴ └─────┘┴┴└─┘└─────────────────┘┴ └─────┘┴┴└─┘└────────┘└┘
doc ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └┘
txt ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └┘
par ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └┘
pid ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴┴
st ────────────────────────────────────┘└───────────────────────────────┘└──────────┘┴┴└┘└
4610 { rw [eq_nil_of_le hln, filter_lt_of_le_bot hln] }
id └──────────┘ └─┘ └─────────────────┘ └─┘
src └──┘└──────────┘┴ └┘└─────────────────┘┴ └┘
typ └──┘└──────────┘┴└─┘└┘└─────────────────┘┴└─┘└┘
doc └──┘ ┴ └┘ ┴ └┘
txt └──┘ ┴ └┘ ┴ └┘
par └──┘ ┴ └┘ ┴ └┘
pid └┘ ┴ └┘ ┴ ┴┴
st ───────────────────────┘└───────────────────────┘┴┴└─
4611 end
st ──┘
4612
4613 @[simp] lemma filter_lt (n m l : ℕ) : (Ico n m).filter (λ x, x < l) = Ico n (min m l) :=
id ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴
src ┴ └─┘ └────┘ ┴ ┴ └─┘ └─┘
typ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ └─┘ ┴ ┴
doc └──┘ └─┘ └─┘
4614 begin
st └─────
4615 cases le_total m l with hml hlm,
id └──────┘ ┴ ┴
src └────┘└──────┘┴ ┴ └───────────┘
typ └────┘└──────┘┴┴┴┴└───────────┘
doc └────┘ ┴ ┴ └───────────┘
txt └────┘ ┴ ┴ └───────────┘
par └────┘ ┴ ┴ └───────────┘
pid ┴ ┴ ┴ └───────────┘
st ────────────────────────────────┘└─
4616 { rw [min_eq_left hml, filter_lt_of_top_le hml] },
id └─────────┘ └─┘ └─────────────────┘ └─┘
src └──┘└─────────┘┴ └┘└─────────────────┘┴ └┘
typ └──┘└─────────┘┴└─┘└┘└─────────────────┘┴└─┘└┘
doc └──┘ ┴ └┘ ┴ └┘
txt └──┘ ┴ └┘ ┴ └┘
par └──┘ ┴ └┘ ┴ └┘
pid └┘ ┴ └┘ ┴ ┴┴
st ───┘└─────────────────┘└───────────────────────┘┴┴└┘└
4617 { rw [min_eq_right hlm, filter_lt_of_ge hlm] }
id └──────────┘ └─┘ └─────────────┘ └─┘
src └──┘└──────────┘┴ └┘└─────────────┘┴ └┘
typ └──┘└──────────┘┴└─┘└┘└─────────────┘┴└─┘└┘
doc └──┘ ┴ └┘ ┴ └┘
txt └──┘ ┴ └┘ ┴ └┘
par └──┘ ┴ └┘ ┴ └┘
pid └┘ ┴ └┘ ┴ ┴┴
st ───────────────────────┘└───────────────────┘┴┴└─
4618 end
st ──┘
4619
4620 lemma filter_le_of_le_bot {n m l : ℕ} (hln : l ≤ n) : (Ico n m).filter (λ x, l ≤ x) = Ico n m :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src ┴ ┴ └─┘ └────┘ ┴ ┴ └─┘
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
doc └─┘ └─┘
4621 filter_eq_self.2 $ assume k hk, le_trans hln (mem.1 hk).1
id └────────────┘┴ ┴ └┘ └──────┘ └─┘ └─┘┴ └┘ ┴
src └────────────┘┴ └──────┘ └─┘┴ ┴
typ └────────────┘┴ ┴ └┘ └──────┘ └─┘ └─┘┴ └┘ ┴
4622
4623 lemma filter_le_of_top_le {n m l : ℕ} (hml : m ≤ l) : (Ico n m).filter (λ x, l ≤ x) = [] :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
src ┴ ┴ └─┘ └────┘ ┴ ┴ └┘
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘
doc └─┘
4624 filter_eq_nil.2 $ assume k hk, not_le_of_gt (lt_of_lt_of_le (mem.1 hk).2 hml)
id └───────────┘┴ ┴ └┘ └──────────┘ └────────────┘ └─┘┴ └┘ ┴ └─┘
src └───────────┘┴ └──────────┘ └────────────┘ └─┘┴ ┴
typ └───────────┘┴ ┴ └┘ └──────────┘ └────────────┘ └─┘┴ └┘ ┴ └─┘
4625
4626 lemma filter_le_of_le {n m l : ℕ} (hnl : n ≤ l) : (Ico n m).filter (λ x, l ≤ x) = Ico l m :=
id ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
src ┴ ┴ └─┘ └────┘ ┴ ┴ └─┘
typ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴
doc └─┘ └─┘
4627 begin
st └─────
4628 cases le_total l m with hlm hml,
id └──────┘ ┴ ┴
src └────┘└──────┘┴ ┴ └───────────┘
typ └────┘└──────┘┴┴┴┴└───────────┘
doc └────┘ ┴ ┴ └───────────┘
txt └────┘ ┴ ┴ └───────────┘
par └────┘ ┴ ┴ └───────────┘
pid ┴ ┴ ┴ └───────────┘
st ────────────────────────────────┘└─
4629 { rw [← append_consecutive hnl hlm, filter_append,
id └────────────────┘ └─┘ └─┘ └───────────┘
src └────┘└────────────────┘┴ ┴ └┘└───────────┘└─
typ └────┘└────────────────┘┴└─┘┴└─┘└┘└───────────┘└─
doc └────┘ ┴ ┴ └┘ └─
txt └────┘ ┴ ┴ └┘ └─
par └────┘ ┴ ┴ └┘ └─
pid └──┘ ┴ ┴ └┘ └─
st ───┘└──────────────────────────────┘└─────────────┘└─
4630 filter_le_of_top_le (le_refl l), filter_le_of_le_bot (le_refl l), nil_append] },
id └─────────────────┘ └─────┘ ┴ └─────────────────┘ └─────┘ ┴ └────────┘
src ─────┘└─────────────────┘┴ └─────┘┴ └─┘└─────────────────┘┴ └─────┘┴ └─┘└────────┘└┘
typ ─────┘└─────────────────┘┴ └─────┘┴┴└─┘└─────────────────┘┴ └─────┘┴┴└─┘└────────┘└┘
doc ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └┘
txt ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └┘
par ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ └┘
pid ─────┘ ┴ ┴ └─┘ ┴ ┴ └─┘ ┴┴
st ────────────────────────────────────┘└───────────────────────────────┘└──────────┘┴┴└┘└
4631 { rw [eq_nil_of_le hml, filter_le_of_top_le hml] }
id └──────────┘ └─┘ └─────────────────┘ └─┘
src └──┘└──────────┘┴ └┘└─────────────────┘┴ └┘
typ └──┘└──────────┘┴└─┘└┘└─────────────────┘┴└─┘└┘
doc └──┘ ┴ └┘ ┴ └┘
txt └──┘ ┴ └┘ ┴ └┘
par └──┘ ┴ └┘ ┴ └┘
pid └┘ ┴ └┘ ┴ ┴┴
st ───────────────────────┘└───────────────────────┘┴┴└─
4632 end
st ──┘
4633
4634 @[simp] lemma filter_le (n m l : ℕ) : (Ico n m).filter (λ x, l ≤ x) = Ico (_root_.max n l) m :=
id ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ └────────┘ ┴ ┴ ┴
src ┴ └─┘ └────┘ ┴ ┴ └─┘ └────────┘
typ ┴ └─┘ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └─┘ └────────┘ ┴ ┴ ┴
doc └──┘ └─┘ └─┘
4635 begin
st └─────
4636 cases le_total n l with hnl hln,
id └──────┘ ┴ ┴
src └────┘└──────┘┴ ┴ └───────────┘
typ └────┘└──────┘┴┴┴┴└───────────┘
doc └────┘ ┴ ┴ └───────────┘
txt └────┘ ┴ ┴ └───────────┘
par └────┘ ┴ ┴ └───────────┘
pid ┴ ┴ ┴ └───────────┘
st ────────────────────────────────┘└─
4637 { rw [max_eq_right hnl, filter_le_of_le hnl] },
id └──────────┘ └─┘ └─────────────┘ └─┘
src └──┘└──────────┘┴ └┘└─────────────┘┴ └┘
typ └──┘└──────────┘┴└─┘└┘└─────────────┘┴└─┘└┘
doc └──┘ ┴ └┘ ┴ └┘
txt └──┘ ┴ └┘ ┴ └┘
par └──┘ ┴ └┘ ┴ └┘
pid └┘ ┴ └┘ ┴ ┴┴
st ───┘└──────────────────┘└───────────────────┘┴┴└┘└
4638 { rw [max_eq_left hln, filter_le_of_le_bot hln] }
id └─────────┘ └─┘ └─────────────────┘ └─┘
src └──┘└─────────┘┴ └┘└─────────────────┘┴ └┘
typ └──┘└─────────┘┴└─┘└┘└─────────────────┘┴└─┘└┘
doc └──┘ ┴ └┘ ┴ └┘
txt └──┘ ┴ └┘ ┴ └┘
par └──┘ ┴ └┘ ┴ └┘
pid └┘ ┴ └┘ ┴ ┴┴
st ──────────────────────┘└───────────────────────┘┴┴└─
4639 end
st ──┘
4640
4641 end Ico
4642
4643 @[simp] theorem enum_from_map_fst : ∀ n (l : list α),
id ┴ └──┘ ┴
src └──┘
typ ┴ └──┘ ┴
doc └──┘
4644 map prod.fst (enum_from n l) = range' n l.length
id └─┘ └──────┘ └───────┘ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘
src └─┘ └──────┘ └───────┘ ┴ └────┘ └─────┘
typ └─┘ └──────┘ └───────┘ ┴ ┴ ┴ └────┘ ┴ ┴└─────┘
doc └────┘
4645 | n [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
4646 | n (a :: l) := congr_arg (cons _) (enum_from_map_fst _ _)
id └┘ └───────┘ └──┘ └───────────────┘
src └┘ └───────┘ └──┘
typ └┘ └───────┘ └──┘ └───────────────┘
4647
4648 @[simp] theorem enum_map_fst (l : list α) :
id └──┘ ┴
src └──┘
typ └──┘ ┴
doc └──┘
4649 map prod.fst (enum l) = range l.length :=
id └─┘ └──────┘ └──┘ ┴ ┴ └───┘ ┴└─────┘
src └─┘ └──────┘ └──┘ ┴ └───┘ └─────┘
typ └─┘ └──────┘ └──┘ ┴ ┴ └───┘ ┴└─────┘
4650 by simp only [enum, enum_from_map_fst, range_eq_range']
id └──┘ └───────────────┘ └─────────────┘
src └─────────┘└──┘└┘└───────────────┘└┘└─────────────┘└─
typ └─────────┘└──┘└┘└───────────────┘└┘└─────────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────
4651
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4652 theorem ilast'_mem : ∀ a l, @ilast' α a l ∈ a :: l
id ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴
src └────┘ ┴ └┘
typ ┴ ┴ └────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴
doc └────┘
4653 | a [] := or.inl rfl
id └┘ └────┘ └─┘
src └┘ └────┘ └─┘
typ └┘ └────┘ └─┘
4654 | a (b::l) := or.inr (ilast'_mem b l)
id ┴└┘┴ └────┘ └────────┘
src └┘ └────┘
typ ┴└┘┴ └────┘ └────────┘
4655
4656 @[simp] lemma nth_le_attach (L : list α) (i) (H : i < L.attach.length) :
id └──┘ ┴ ┴ ┴ ┴└─────┘└─────┘
src └──┘ ┴ └─────┘└─────┘
typ └──┘ ┴ ┴ ┴ ┴└─────┘└─────┘
doc └──┘ └─────┘
4657 (L.attach.nth_le i H).1 = L.nth_le i (length_attach L ▸ H) :=
id ┴└─────┘└─────┘ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ └───────────┘ ┴ ┴ ┴
src └─────┘└─────┘ ┴ ┴ └─────┘ └───────────┘ ┴
typ ┴└─────┘└─────┘ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ └───────────┘ ┴ ┴ ┴
doc └─────┘
4658 calc (L.attach.nth_le i H).1
id ┴└─────┘└─────┘ ┴ ┴ ┴
src └─────┘└─────┘ ┴
typ ┴└─────┘└─────┘ ┴ ┴ ┴
doc └─────┘
4659 = (L.attach.map subtype.val).nth_le i (by simpa using H) : by rw nth_le_map'
id ┴└─────┘└──┘ └─────────┘ └────┘ ┴ ┴ └─────────┘
src └─────┘└──┘ └─────────┘ └────┘ └──────────┘ └─┘└─────────┘┴
typ ┴└─────┘└──┘ └─────────┘ └────┘ ┴ └──────────┘┴ └─┘└─────────┘┴
doc └─────┘ └──────────┘ └─┘ ┴
txt └──────────┘ └─┘ ┴
par └──────────┘ └─┘ ┴
pid ┴└────┘ ┴ ┴
st └────────────┘ └──────────────┘
4660 ... = L.nth_le i _ : by congr; apply attach_map_val
id ┴└─────┘ ┴ └────────────┘
src └─────┘ └───┘ └────┘└────────────┘└
typ ┴└─────┘ ┴ └───┘ └────┘└────────────┘└
doc └────┘ └
txt └───┘ └────┘ └
par └───┘ └────┘ └
pid ┴ └
st └────────────────────────────
4661
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4662 @[simp] lemma nth_le_range {n} (i) (H : i < (range n).length) :
id ┴ ┴ └───┘ ┴ └────┘
src ┴ └───┘ └────┘
typ ┴ ┴ └───┘ ┴ └────┘
doc └──┘
4663 nth_le (range n) i H = i :=
id └────┘ └───┘ ┴ ┴ ┴ ┴ ┴
src └────┘ └───┘ ┴
typ └────┘ └───┘ ┴ ┴ ┴ ┴ ┴
4664 option.some.inj $ by rw [← nth_le_nth _, nth_range (by simpa using H)]
id └─────────────┘ └────────┘ └───────┘ ┴
src └─────────────┘ └────┘└────────┘└──┘└───────┘┴ ┴└──────────┘ └──
typ └─────────────┘ └────┘└────────┘└──┘└───────┘┴ ┴└──────────┘┴└──
doc └────┘ └──┘ ┴ ┴└──────────┘ └──
txt └────┘ └──┘ ┴ ┴└──────────┘ └──
par └────┘ └──┘ ┴ ┴└──────────┘ └──
pid └──┘ └──┘ ┴ └───────────┘ └┘└
st └─────────────────┘└─────────────┘└────────────┘┴┴└
4665
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4666 theorem of_fn_eq_pmap {α n} {f : fin n → α} :
id └─┘ ┴ ┴
src └─┘
typ └─┘ ┴ ┴
4667 of_fn f = pmap (λ i hi, f ⟨i, hi⟩) (range n) (λ _, mem_range.1) :=
id └───┘ ┴ ┴ └──┘ ┴ └┘ ┴ ┴ └┘ └───┘ ┴ ┴ └───────┘┴
src └───┘ ┴ └──┘ └───┘ └───────┘┴
typ └───┘ ┴ ┴ └──┘ ┴ └┘ ┴ ┴ └┘ └───┘ ┴ ┴ └───────┘┴
doc └──┘
4668 by rw [pmap_eq_map_attach]; from ext_le (by simp)
id └────────────────┘ └────┘
src └──┘└────────────────┘┴ └───┘└────┘┴ ┴└──┘└─
typ └──┘└────────────────┘┴ └───┘└────┘┴ ┴└──┘└─
doc └──┘ ┴ └───┘ ┴ ┴└──┘└─
txt └──┘ ┴ └───┘ ┴ ┴└──┘└─
par └──┘ ┴ └───┘ ┴ ┴└──┘└─
pid └┘ ┴ └───┘ ┴ └──────
st └─────────────────────┘┴└───────────────┘└───┘└─
4669 (λ i hi1 hi2, by simp at hi1; simp [nth_le_of_fn f ⟨i, hi1⟩])
id └──────────┘ ┴ ┴ └─┘
src ─┘ └──────────┘ ┴└─────────┘└┘└────┘└──────────┘┴ ┴ └┘ └┘└─
typ ─┘ └──────────┘ ┴└─────────┘└┘└────┘└──────────┘┴┴┴ ┴└┘└─┘└┘└─
doc ─┘ └──────────┘ ┴└─────────┘└┘└────┘ ┴ ┴ └┘ └┘└─
txt ─┘ └──────────┘ ┴└─────────┘└┘└────┘ ┴ ┴ └┘ └┘└─
par ─┘ └──────────┘ ┴└─────────┘└┘└────┘ ┴ ┴ └┘ └┘└─
pid ─┘ └──────────┘ └──────────────────┘ ┴ ┴ └┘ └─┘└
st ─────────────────┘└──────────────────────────────────────────┘└─
4670
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4671 theorem nodup_of_fn {α n} {f : fin n → α} (hf : function.injective f) :
id └─┘ ┴ ┴ └────────────────┘ ┴
src └─┘ └────────────────┘
typ └─┘ ┴ ┴ └────────────────┘ ┴
4672 nodup (of_fn f) :=
id └───┘ └───┘ ┴
src └───┘ └───┘
typ └───┘ └───┘ ┴
doc └───┘
4673 by rw of_fn_eq_pmap; from nodup_pmap
id └───────────┘ └────────┘
src └─┘└───────────┘ └───┘└────────┘└
typ └─┘└───────────┘ └───┘└────────┘└
doc └─┘ └───┘ └
txt └─┘ └───┘ └
par └─┘ └───┘ └
pid ┴ └───┘ └
st └──────────────────────────────────
4674 (λ _ _ _ _ H, fin.veq_of_eq $ hf H) (nodup_range n)
id └───────────┘ └┘ └─────────┘ ┴
src ─┘ └──────────┘└───────────┘┴ ┴ ┴ └┘ └─────────┘┴ └─
typ ─┘ └──────────┘└───────────┘┴ ┴└┘┴ └┘ └─────────┘┴┴└─
doc ─┘ └──────────┘ ┴ ┴ ┴ └┘ ┴ └─
txt ─┘ └──────────┘ ┴ ┴ ┴ └┘ ┴ └─
par ─┘ └──────────┘ ┴ ┴ ┴ └┘ ┴ └─
pid ─┘ └──────────┘ ┴ ┴ ┴ └┘ ┴ ┴└
st ──────────────────────────────────────────────────────
4675
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4676 section tfae
4677
4678 /- tfae: The Following (propositions) Are Equivalent -/
4679
4680 theorem tfae_nil : tfae [] := forall_mem_nil _
id └──┘ └┘ └────────────┘
src └──┘ └┘ └────────────┘
typ └──┘ └┘ └────────────┘
4681 theorem tfae_singleton (p) : tfae [p] := by simp [tfae, -eq_iff_iff]
id └──┘ ┴┴┴ └──┘
src └──┘ ┴ ┴ └────┘└──┘└──────────────
typ └──┘ ┴┴┴ └────┘└──┘└──────────────
doc └────┘ └──────────────
txt └────┘ └──────────────
par └────┘ └──────────────
pid ┴┴ └────────────┘└
st └─────────────────────────
4682
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4683 theorem tfae_cons_of_mem {a b} {l : list Prop} (h : b ∈ l) :
id └──┘ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴
4684 tfae (a::l) ↔ (a ↔ b) ∧ tfae l :=
id └──┘ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘ └┘ ┴ ┴ ┴ └──┘
typ └──┘ ┴└┘┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
4685 ⟨λ H, ⟨H a (by simp) b (or.inr h), λ p hp q hq, H _ (or.inr hp) _ (or.inr hq)⟩,
id ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ └┘ ┴ └────┘ └┘ └────┘ └┘
src └──┘ └────┘ └────┘ └────┘
typ ┴ ┴ ┴ └──┘ ┴ └────┘ ┴ ┴ └┘ ┴ └┘ ┴ └────┘ └┘ └────┘ └┘
doc └──┘
txt └──┘
par └──┘
st └───┘
4686 begin
st └─────
4687 rintro ⟨ab, H⟩ p (rfl | hp) q (rfl | hq),
src └──────────────────────────────────────┘
typ └──────────────────────────────────────┘
doc └──────────────────────────────────────┘
txt └──────────────────────────────────────┘
par └──────────────────────────────────────┘
pid └────────────────────────────────┘
st ──────────────────────────────────────────┘└─
4688 { refl },
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st ────┘└───┘└┘└
4689 { exact ab.trans (H _ h _ hq) },
id └──────┘ ┴ ┴ └┘
src └────┘└──────┘┴ └─┘ └─┘ └┘
typ └────┘└──────┘┴ ┴└─┘┴└─┘└┘└┘
doc └────┘ ┴ └─┘ └─┘ └┘
txt └────┘ ┴ └─┘ └─┘ └┘
par └────┘ ┴ └─┘ └─┘ └┘
pid ┴ ┴ └─┘ └─┘ ┴┴
st ────┘└──────────────────────────┘└┘└
4690 { exact (ab.trans (H _ h _ hp)).symm },
id └──────┘ ┴ ┴ └┘
src └────┘ └──────┘┴ └─┘ └─┘ └──────┘
typ └────┘ └──────┘┴ ┴└─┘┴└─┘└┘└──────┘
doc └────┘ ┴ └─┘ └─┘ └──────┘
txt └────┘ ┴ └─┘ └─┘ └──────┘
par └────┘ ┴ └─┘ └─┘ └──────┘
pid ┴ ┴ └─┘ └─┘ └────┘└┘
st ────┘└─────────────────────────────────┘└┘└
4691 { exact H _ hp _ hq }
id ┴ └┘ └┘
src └────┘ └─┘ └─┘ ┴
typ └────┘┴└─┘└┘└─┘└┘┴
doc └────┘ └─┘ └─┘ ┴
txt └────┘ └─┘ └─┘ ┴
par └────┘ └─┘ └─┘ ┴
pid ┴ └─┘ └─┘ ┴
st ──────────────────────┘└─
4692 end⟩
st ──┘
4693
4694 theorem tfae_cons_cons {a b} {l : list Prop} : tfae (a::b::l) ↔ (a ↔ b) ∧ tfae (b::l) :=
id └──┘ └──┘ ┴└┘┴└┘┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴└┘┴
src └──┘ └──┘ └┘ └┘ ┴ ┴ ┴ └──┘ └┘
typ └──┘ └──┘ ┴└┘┴└┘┴ ┴ ┴ ┴ ┴ ┴ └──┘ ┴└┘┴
4695 tfae_cons_of_mem (or.inl rfl)
id └──────────────┘ └────┘ └─┘
src └──────────────┘ └────┘ └─┘
typ └──────────────┘ └────┘ └─┘
4696
4697 theorem tfae_of_forall (b : Prop) (l : list Prop) (h : ∀ a ∈ l, a ↔ b) : tfae l :=
id └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
src └──┘ ┴ └──┘
typ └──┘ ┴ ┴ ┴ ┴ ┴ └──┘ ┴
4698 λ a₁ h₁ a₂ h₂, (h _ h₁).trans (h _ h₂).symm
id └┘ └┘ └┘ └┘ ┴ └┘ └───┘ ┴ └┘ └──┘
src └───┘ └──┘
typ └┘ └┘ └┘ └┘ ┴ └┘ └───┘ ┴ └┘ └──┘
4699
4700 theorem tfae_of_cycle {a b} {l : list Prop} :
id └──┘
src └──┘
typ └──┘
4701 list.chain (→) a (b::l) → (ilast' b l → a) → tfae (a::b::l) :=
id └────────┘ ┴ ┴ ┴└┘┴ └────┘ ┴ ┴ ┴ ┴ └──┘ ┴└┘┴└┘┴
src └────────┘ └┘ └────┘ └──┘ └┘ └┘
typ └────────┘ ┴ ┴ ┴└┘┴ └────┘ ┴ ┴ ┴ ┴ └──┘ ┴└┘┴└┘┴
doc └────────┘ └────┘
4702 begin
st └─────
4703 induction l with c l IH generalizing a b; simp only [tfae_cons_cons, tfae_singleton, and_true, chain_cons, chain.nil] at *,
id ┴ └────────────┘ └────────────┘ └──────┘ └────────┘ └───────┘
src └────────┘ └───────────────────────────┘ └─────────┘└────────────┘└┘└────────────┘└┘└──────┘└┘└────────┘└┘└───────┘└────┘
typ └────────┘┴└───────────────────────────┘ └─────────┘└────────────┘└┘└────────────┘└┘└──────┘└┘└────────┘└┘└───────┘└────┘
doc └────────┘ └───────────────────────────┘ └─────────┘ └┘ └┘ └┘ └┘ └────┘
txt └────────┘ └───────────────────────────┘ └─────────┘ └┘ └┘ └┘ └┘ └────┘
par └────────┘ └───────────────────────────┘ └─────────┘ └┘ └┘ └┘ └┘ └────┘
pid ┴ ┴└─────────┘└───────────────┘ ┴└──┘└┘ └┘ └┘ └┘ └┘ ┴┴└──┘
st ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘└─
4704 { intros a b, exact iff.intro a b },
id └───────┘ ┴ ┴
src └────────┘ └────┘└───────┘┴ ┴ ┴
typ └────────┘ └────┘└───────┘┴┴┴┴┴
doc └────────┘ └────┘ ┴ ┴ ┴
txt └────────┘ └────┘ ┴ ┴ ┴
par └────────┘ └────┘ ┴ ┴ ┴
pid └──┘ ┴ ┴ ┴ ┴
st ───┘└────────┘└────────────────────┘└┘└
4705 rintros ⟨ab,⟨bc,ch⟩⟩ la,
src └─────────────────────┘
typ └─────────────────────┘
doc └─────────────────────┘
txt └─────────────────────┘
par └─────────────────────┘
pid └──────────────┘
st ────────────────────────┘└─
4706 have := IH ⟨bc,ch⟩ (ab ∘ la),
id └┘ └┘ └┘ └┘ ┴ └┘
src └──────┘ ┴ ┴ └┘ ┴┴┴ ┴
typ └──────┘└┘┴ └┘┴└┘└┘ └┘┴┴┴└┘┴
doc └──────┘ ┴ ┴ └┘ ┴ ┴ ┴
txt └──────┘ ┴ ┴ └┘ ┴ ┴ ┴
par └──────┘ ┴ ┴ └┘ ┴ ┴ ┴
pid └───┘└─┘ ┴ ┴ └┘ ┴ ┴ ┴
st ─────────────────────────────┘└─
4707 exact ⟨⟨ab, la ∘ (this.2 c (or.inl rfl) _ (ilast'_mem _ _)).1 ∘ bc⟩, this⟩
id └┘ └┘ ┴ └────┘ └─┘ └────────┘ └┘ └──┘
src └────┘ └┘ ┴ ┴ └─┘ ┴ └────┘┴└─┘└──┘ └────────┘└───────┘ ┴ └─┘ └┘
typ └────┘ └┘└┘└┘┴ ┴ └─┘┴┴ └────┘┴└─┘└──┘ └────────┘└───────┘ ┴└┘└─┘└──┘└┘
doc └────┘ └┘ ┴ ┴ └─┘ ┴ ┴ └──┘ └───────┘ ┴ └─┘ └┘
txt └────┘ └┘ ┴ ┴ └─┘ ┴ ┴ └──┘ └───────┘ ┴ └─┘ └┘
par └────┘ └┘ ┴ ┴ └─┘ ┴ ┴ └──┘ └───────┘ ┴ └─┘ └┘
pid ┴ └┘ ┴ ┴ └─┘ ┴ ┴ └──┘ └───────┘ ┴ └─┘ ┴┴
st ────────────────────────────────────────────────────────────────────────────┘
4708 end
st └─┘
4709
4710 theorem tfae.out {l} (h : tfae l) (n₁ n₂)
id └──┘ ┴
src └──┘
typ └──┘ ┴
4711 (h₁ : n₁ < list.length l . tactic.exact_dec_trivial)
id └┘ ┴ └─────────┘ ┴ ┴
src ┴ └─────────┘
typ └┘ ┴ └─────────┘ ┴ ┴
doc ┴
4712 (h₂ : n₂ < list.length l . tactic.exact_dec_trivial) :
id └┘ ┴ └─────────┘ ┴ ┴
src ┴ └─────────┘
typ └┘ ┴ └─────────┘ ┴ ┴
doc ┴
4713 list.nth_le l n₁ h₁ ↔ list.nth_le l n₂ h₂ :=
id └─────────┘ ┴ └┘ └┘ ┴ └─────────┘ ┴ └┘ └┘
src └─────────┘ ┴ └─────────┘
typ └─────────┘ ┴ └┘ └┘ ┴ └─────────┘ ┴ └┘ └┘
4714 h _ (list.nth_le_mem _ _ _) _ (list.nth_le_mem _ _ _)
id ┴ └─────────────┘ └─────────────┘
src └─────────────┘ └─────────────┘
typ ┴ └─────────────┘ └─────────────┘
4715
4716 end tfae
4717
4718 lemma rotate_mod (l : list α) (n : ℕ) : l.rotate (n % l.length) = l.rotate n :=
id └──┘ ┴ ┴ ┴└─────┘ ┴ ┴ ┴└─────┘ ┴ ┴└─────┘ ┴
src └──┘ ┴ └─────┘ ┴ └─────┘ ┴ └─────┘
typ └──┘ ┴ ┴ ┴└─────┘ ┴ ┴ ┴└─────┘ ┴ ┴└─────┘ ┴
doc └─────┘ └─────┘
4719 by simp [rotate]
id └────┘
src └────┘└────┘└─
typ └────┘└────┘└─
doc └────┘└────┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └──────────────
4720
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4721 @[simp] lemma rotate_nil (n : ℕ) : ([] : list α).rotate n = [] := by cases n; refl
id ┴ └┘ └──┘ ┴ └────┘ ┴ ┴ └┘ ┴
src ┴ └┘ └──┘ └────┘ ┴ └┘ └────┘ └────
typ ┴ └┘ └──┘ ┴ └────┘ ┴ ┴ └┘ └────┘┴ └────
doc └──┘ └────┘ └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
4722
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4723 @[simp] lemma rotate_zero (l : list α) : l.rotate 0 = l := by simp [rotate]
id └──┘ ┴ ┴└─────┘ ┴ ┴ └────┘
src └──┘ └─────┘ ┴ └────┘└────┘└─
typ └──┘ ┴ ┴└─────┘ ┴ ┴ └────┘└────┘└─
doc └──┘ └─────┘ └────┘└────┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └──────────────
4724
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4725 @[simp] lemma rotate'_nil (n : ℕ) : ([] : list α).rotate' n = [] := by cases n; refl
id ┴ └┘ └──┘ ┴ └─────┘ ┴ ┴ └┘ ┴
src ┴ └┘ └──┘ └─────┘ ┴ └┘ └────┘ └────
typ ┴ └┘ └──┘ ┴ └─────┘ ┴ ┴ └┘ └────┘┴ └────
doc └──┘ └─────┘ └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
4726
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4727 @[simp] lemma rotate'_zero (l : list α) : l.rotate' 0 = l := by cases l; refl
id └──┘ ┴ ┴└──────┘ ┴ ┴ ┴
src └──┘ └──────┘ ┴ └────┘ └────
typ └──┘ ┴ ┴└──────┘ ┴ ┴ └────┘┴ └────
doc └──┘ └──────┘ └────┘ └────
txt └────┘ └────
par └────┘ └────
pid ┴ └
st └──────────────
4728
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4729 lemma rotate'_cons_succ (l : list α) (a : α) (n : ℕ) :
id └──┘ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴
4730 (a :: l : list α).rotate' n.succ = (l ++ [a]).rotate' n := by simp [rotate']
id ┴ └┘ ┴ └──┘ ┴ └─────┘ ┴└───┘ ┴ ┴ └┘ ┴┴┴ └─────┘ ┴ └─────┘
src └┘ └──┘ └─────┘ └───┘ ┴ └┘ ┴ ┴ └─────┘ └────┘└─────┘└─
typ ┴ └┘ ┴ └──┘ ┴ └─────┘ ┴└───┘ ┴ ┴ └┘ ┴┴┴ └─────┘ ┴ └────┘└─────┘└─
doc └─────┘ └─────┘ └────┘└─────┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st └───────────────
4731
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4732 @[simp] lemma length_rotate' : ∀ (l : list α) (n : ℕ), (l.rotate' n).length = l.length
id ┴ └──┘ ┴ ┴ ┴└──────┘ ┴ └────┘ ┴ ┴└─────┘
src └──┘ ┴ └──────┘ └────┘ ┴ └─────┘
typ ┴ └──┘ ┴ ┴ ┴└──────┘ ┴ └────┘ ┴ ┴└─────┘
doc └──┘ └──────┘
4733 | [] n := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
4734 | (a::l) 0 := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
4735 | (a::l) (n+1) := by rw [list.rotate', length_rotate' (l ++ [a]) n]; simp
id └┘ ┴ └──────────┘ └────────────┘ ┴ └┘ ┴┴┴ ┴
src └┘ ┴ └──┘└──────────┘└┘ ┴ ┴└┘┴┴ ┴└┘ ┴ └────
typ └┘ ┴ └──┘└──────────┘└┘└────────────┘┴ ┴┴└┘┴┴┴┴└┘┴┴ └────
doc └──┘└──────────┘└┘ ┴ ┴ ┴ └┘ ┴ └────
txt └──┘ └┘ ┴ ┴ ┴ └┘ ┴ └────
par └──┘ └┘ ┴ ┴ ┴ └┘ ┴ └────
pid └┘ └┘ ┴ ┴ ┴ └┘ ┴ └
st └───────────────┘└───────────────────────────┘┴└──────
4736
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4737 lemma rotate'_eq_take_append_drop : ∀ {l : list α} {n : ℕ}, n ≤ l.length →
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴└─────┘
src └──┘ ┴ ┴ └─────┘
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴└─────┘
4738 l.rotate' n = l.drop n ++ l.take n
id ┴└──────┘ ┴ ┴ ┴└───┘ ┴ └┘ ┴└───┘ ┴
src └──────┘ ┴ └───┘ └┘ └───┘
typ ┴└──────┘ ┴ ┴ ┴└───┘ ┴ └┘ ┴└───┘ ┴
doc └──────┘
4739 | [] n h := by simp [drop_append_of_le_length h]
id └┘ └──────────────────────┘ ┴
src └┘ └────┘└──────────────────────┘┴ └┘
typ └┘ └────┘└──────────────────────┘┴┴└┘
doc └────┘ ┴ └┘
txt └────┘ ┴ └┘
par └────┘ ┴ └┘
pid ┴┴ ┴ ┴┴
st └─────────────────────────────────┘
4740 | l 0 h := by simp [take_append_of_le_length h]
id └──────────────────────┘ ┴
src └────┘└──────────────────────┘┴ └┘
typ └────┘└──────────────────────┘┴┴└┘
doc └────┘ ┴ └┘
txt └────┘ ┴ └┘
par └────┘ ┴ └┘
pid ┴┴ ┴ ┴┴
st └─────────────────────────────────┘
4741 | (a::l) (n+1) h :=
id ┴└┘┴ ┴┴ ┴
src └┘ ┴
typ ┴└┘┴ ┴┴ ┴
4742 have hnl : n ≤ l.length, from le_of_succ_le_succ h,
id ┴ └─────┘ └────────────────┘
src ┴ └─────┘ └────────────────┘
typ ┴ └─────┘ └────────────────┘
4743 have hnl' : n ≤ (l ++ [a]).length,
id ┴ └┘ ┴ ┴ └────┘
src ┴ └┘ ┴ ┴ └────┘
typ ┴ └┘ ┴ ┴ └────┘
4744 by rw [length_append, length_cons, list.length, zero_add];
id └───────────┘ └─────────┘ └─────────┘ └──────┘
src └──┘└───────────┘└┘└─────────┘└┘└─────────┘└┘└──────┘┴
typ └──┘└───────────┘└┘└─────────┘└┘└─────────┘└┘└──────┘┴
doc └──┘ └┘ └┘ └┘ ┴
txt └──┘ └┘ └┘ └┘ ┴
par └──┘ └┘ └┘ └┘ ┴
pid └┘ └┘ └┘ └┘ ┴
st └────────────────┘└───────────┘└───────────┘└────────┘┴└─
4745 exact (le_of_succ_le h),
id └───────────┘ ┴
src └────┘ └───────────┘┴ ┴
typ └────┘ └───────────┘┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ──────────────────────────┘
4746 by rw [rotate'_cons_succ, rotate'_eq_take_append_drop hnl', drop, take,
id └───────────────┘ └─────────────────────────┘ └──┘ └──┘ └──┘
src └──┘└───────────────┘└┘ ┴ └┘└──┘└┘└──┘└─
typ └──┘└───────────────┘└┘└─────────────────────────┘┴└──┘└┘└──┘└┘└──┘└─
doc └──┘ └┘ ┴ └┘ └┘ └─
txt └──┘ └┘ ┴ └┘ └┘ └─
par └──┘ └┘ ┴ └┘ └┘ └─
pid └┘ └┘ ┴ └┘ └┘ └─
st └────────────────────┘└────────────────────────────────┘└────┘└────┘└─
4747 drop_append_of_le_length hnl, take_append_of_le_length hnl];
id └──────────────────────┘ └─┘ └──────────────────────┘ └─┘
src ────┘└──────────────────────┘┴ └┘└──────────────────────┘┴ ┴
typ ────┘└──────────────────────┘┴└─┘└┘└──────────────────────┘┴└─┘┴
doc ────┘ ┴ └┘ ┴ ┴
txt ────┘ ┴ └┘ ┴ ┴
par ────┘ ┴ └┘ ┴ ┴
pid ────┘ ┴ └┘ ┴ ┴
st ────────────────────────────────┘└────────────────────────────┘┴└─
4748 simp
src └────
typ └────
doc └────
txt └────
par └────
pid └
st ────────
4749
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4750 lemma rotate'_rotate' : ∀ (l : list α) (n m : ℕ), (l.rotate' n).rotate' m = l.rotate' (n + m)
id ┴ └──┘ ┴ ┴ ┴└──────┘ ┴ └─────┘ ┴ ┴ ┴└──────┘ ┴ ┴ ┴
src └──┘ ┴ └──────┘ └─────┘ ┴ └──────┘ ┴
typ ┴ └──┘ ┴ ┴ ┴└──────┘ ┴ └─────┘ ┴ ┴ ┴└──────┘ ┴ ┴ ┴
doc └──────┘ └─────┘ └──────┘
4751 | (a::l) 0 m := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4752 | [] n m := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4753 | (a::l) (n+1) m := by rw [rotate'_cons_succ, rotate'_rotate', add_right_comm, rotate'_cons_succ]
id └┘ ┴ └───────────────┘ └─────────────┘ └────────────┘ └───────────────┘
src └┘ ┴ └──┘└───────────────┘└┘ └┘└────────────┘└┘└───────────────┘└─
typ └┘ ┴ └──┘└───────────────┘└┘└─────────────┘└┘└────────────┘└┘└───────────────┘└─
doc └──┘ └┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └┘ └─
par └──┘ └┘ └┘ └┘ └─
pid └┘ └┘ └┘ └┘ ┴└
st └────────────────────┘└───────────────┘└──────────────┘└─────────────────┘┴└
4754
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4755 @[simp] lemma rotate'_length (l : list α) : rotate' l l.length = l :=
id └──┘ ┴ └─────┘ ┴ ┴└─────┘ ┴ ┴
src └──┘ └─────┘ └─────┘ ┴
typ └──┘ ┴ └─────┘ ┴ ┴└─────┘ ┴ ┴
doc └──┘ └─────┘
4756 by rw rotate'_eq_take_append_drop (le_refl _); simp
id └─────────────────────────┘ └─────┘
src └─┘└─────────────────────────┘┴ └─────┘└─┘ └────
typ └─┘└─────────────────────────┘┴ └─────┘└─┘ └────
doc └─┘ ┴ └─┘ └────
txt └─┘ ┴ └─┘ └────
par └─┘ ┴ └─┘ └────
pid ┴ ┴ └─┘ └
st └─────────────────────────────────────────────────
4757
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4758 @[simp] lemma rotate'_length_mul (l : list α) : ∀ n : ℕ, l.rotate' (l.length * n) = l
id └──┘ ┴ ┴ ┴ ┴└──────┘ ┴└─────┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └──────┘ └─────┘ ┴ ┴
typ └──┘ ┴ ┴ ┴ ┴└──────┘ ┴└─────┘ ┴ ┴ ┴ ┴
doc └──┘ └──────┘
4759 | 0 := by simp
src └───┘
typ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4760 | (n+1) :=
id ┴┴
src ┴
typ ┴┴
4761 calc l.rotate' (l.length * (n + 1)) =
id ┴└──────┘ ┴└─────┘ ┴ ┴
src └──────┘ └─────┘ ┴ ┴
typ ┴└──────┘ ┴└─────┘ ┴ ┴
doc └──────┘
4762 (l.rotate' (l.length * n)).rotate' (l.rotate' (l.length * n)).length :
id ┴└──────┘ ┴└─────┘ ┴ └─────┘ ┴└──────┘ ┴└─────┘ ┴ └────┘
src └──────┘ └─────┘ ┴ └─────┘ └──────┘ └─────┘ ┴ └────┘
typ ┴└──────┘ ┴└─────┘ ┴ └─────┘ ┴└──────┘ ┴└─────┘ ┴ └────┘
doc └──────┘ └─────┘ └──────┘
4763 by simp [-rotate'_length, nat.mul_succ, rotate'_rotate']
id └──────────┘ └─────────────┘
src └─────────────────────┘└──────────┘└┘└─────────────┘└┘
typ └─────────────────────┘└──────────┘└┘└─────────────┘└┘
doc └─────────────────────┘ └┘ └┘
txt └─────────────────────┘ └┘ └┘
par └─────────────────────┘ └┘ └┘
pid ┴└────────────────┘ └┘ ┴┴
st └─────────────────────────────────────────────────────┘
4764 ... = l : by rw [rotate'_length, rotate'_length_mul]
id ┴ └────────────┘ └────────────────┘
src └──┘└────────────┘└┘ └─
typ ┴ └──┘└────────────┘└┘└────────────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └─────────────────┘└──────────────────┘┴└
4765
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4766 lemma rotate'_mod (l : list α) (n : ℕ) : l.rotate' (n % l.length) = l.rotate' n :=
id └──┘ ┴ ┴ ┴└──────┘ ┴ ┴ ┴└─────┘ ┴ ┴└──────┘ ┴
src └──┘ ┴ └──────┘ ┴ └─────┘ ┴ └──────┘
typ └──┘ ┴ ┴ ┴└──────┘ ┴ ┴ ┴└─────┘ ┴ ┴└──────┘ ┴
doc └──────┘ └──────┘
4767 calc l.rotate' (n % l.length) = (l.rotate' (n % l.length)).rotate'
id ┴└──────┘ ┴ ┴ ┴└─────┘ ┴└──────┘ ┴ ┴ ┴└─────┘ └─────┘
src └──────┘ ┴ └─────┘ └──────┘ ┴ └─────┘ └─────┘
typ ┴└──────┘ ┴ ┴ ┴└─────┘ ┴└──────┘ ┴ ┴ ┴└─────┘ └─────┘
doc └──────┘ └──────┘ └─────┘
4768 ((l.rotate' (n % l.length)).length * (n / l.length)) : by rw rotate'_length_mul
id ┴└──────┘ ┴ ┴ ┴└─────┘ └────┘ ┴ ┴ ┴ ┴└─────┘ └────────────────┘
src └──────┘ ┴ └─────┘ └────┘ ┴ ┴ └─────┘ └─┘└────────────────┘┴
typ ┴└──────┘ ┴ ┴ ┴└─────┘ └────┘ ┴ ┴ ┴ ┴└─────┘ └─┘└────────────────┘┴
doc └──────┘ └─┘ ┴
txt └─┘ ┴
par └─┘ ┴
pid ┴ ┴
st └─────────────────────┘
4769 ... = l.rotate' n : by rw [rotate'_rotate', length_rotate', nat.mod_add_div]
id ┴└──────┘ ┴ └─────────────┘ └────────────┘ └─────────────┘
src └──────┘ └──┘└─────────────┘└┘└────────────┘└┘└─────────────┘└─
typ ┴└──────┘ ┴ └──┘└─────────────┘└┘└────────────┘└┘└─────────────┘└─
doc └──────┘ └──┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └──────────────────┘└──────────────┘└───────────────┘┴└
4770
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4771 lemma rotate_eq_rotate' (l : list α) (n : ℕ) : l.rotate n = l.rotate' n :=
id └──┘ ┴ ┴ ┴└─────┘ ┴ ┴ ┴└──────┘ ┴
src └──┘ ┴ └─────┘ ┴ └──────┘
typ └──┘ ┴ ┴ ┴└─────┘ ┴ ┴ ┴└──────┘ ┴
doc └─────┘ └──────┘
4772 if h : l.length = 0 then by simp [length_eq_zero, *] at *
id └┘ ┴└─────┘ ┴ └────────────┘
src └┘ └─────┘ ┴ └────┘└────────────┘└────────┘
typ └┘ ┴└─────┘ ┴ └────┘└────────────┘└────────┘
doc └────┘ └────────┘
txt └────┘ └────────┘
par └────┘ └────────┘
pid ┴┴ └──┘┴└──┘┴
st └─────────────────────────────┘
4773 else by
st └
4774 rw [← rotate'_mod, rotate'_eq_take_append_drop (le_of_lt (nat.mod_lt _ (nat.pos_of_ne_zero h)))];
id └─────────┘ └─────────────────────────┘ └──────┘ └────────┘ └────────────────┘ ┴
src └────┘└─────────┘└┘└─────────────────────────┘┴ └──────┘┴ └────────┘└─┘ └────────────────┘┴ └──┘
typ └────┘└─────────┘└┘└─────────────────────────┘┴ └──────┘┴ └────────┘└─┘ └────────────────┘┴┴└──┘
doc └────┘ └┘ ┴ ┴ └─┘ ┴ └──┘
txt └────┘ └┘ ┴ ┴ └─┘ ┴ └──┘
par └────┘ └┘ ┴ ┴ └─┘ ┴ └──┘
pid └──┘ └┘ ┴ ┴ └─┘ ┴ └──┘
st ──────────────────┘└────────────────────────────────────────────────────────────────────────────┘┴└─
4775 simp [rotate]
id └────┘
src └────┘└────┘└─
typ └────┘└────┘└─
doc └────┘└────┘└─
txt └────┘ └─
par └────┘ └─
pid ┴┴ ┴└
st ────────────────
4776
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4777 lemma rotate_cons_succ (l : list α) (a : α) (n : ℕ) :
id └──┘ ┴ ┴ ┴
src └──┘ ┴
typ └──┘ ┴ ┴ ┴
4778 (a :: l : list α).rotate n.succ = (l ++ [a]).rotate n :=
id ┴ └┘ ┴ └──┘ ┴ └────┘ ┴└───┘ ┴ ┴ └┘ ┴┴┴ └────┘ ┴
src └┘ └──┘ └────┘ └───┘ ┴ └┘ ┴ ┴ └────┘
typ ┴ └┘ ┴ └──┘ ┴ └────┘ ┴└───┘ ┴ ┴ └┘ ┴┴┴ └────┘ ┴
doc └────┘ └────┘
4779 by rw [rotate_eq_rotate', rotate_eq_rotate', rotate'_cons_succ]
id └───────────────┘ └───────────────┘ └───────────────┘
src └──┘└───────────────┘└┘└───────────────┘└┘└───────────────┘└─
typ └──┘└───────────────┘└┘└───────────────┘└┘└───────────────┘└─
doc └──┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └────────────────────┘└─────────────────┘└─────────────────┘┴└
4780
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4781 @[simp] lemma mem_rotate : ∀ {l : list α} {a : α} {n : ℕ}, a ∈ l.rotate n ↔ a ∈ l
id ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴
src └──┘ ┴ ┴ └─────┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴ ┴ ┴ ┴└─────┘ ┴ ┴ ┴ ┴ ┴
doc └──┘ └─────┘
4782 | [] _ n := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4783 | (a::l) _ 0 := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4784 | (a::l) _ (n+1) := by simp [rotate_cons_succ, mem_rotate, or.comm]
id └┘ ┴ └──────────────┘ └─────┘
src └┘ ┴ └────┘└──────────────┘└┘ └┘└─────┘└─
typ └┘ ┴ └────┘└──────────────┘└┘└────────┘└┘└─────┘└─
doc └────┘ └┘ └┘ └─
txt └────┘ └┘ └┘ └─
par └────┘ └┘ └┘ └─
pid ┴┴ └┘ └┘ ┴└
st └─────────────────────────────────────────────
4785
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4786 @[simp] lemma length_rotate (l : list α) (n : ℕ) : (l.rotate n).length = l.length :=
id └──┘ ┴ ┴ ┴└─────┘ ┴ └────┘ ┴ ┴└─────┘
src └──┘ ┴ └─────┘ └────┘ ┴ └─────┘
typ └──┘ ┴ ┴ ┴└─────┘ ┴ └────┘ ┴ ┴└─────┘
doc └──┘ └─────┘
4787 by rw [rotate_eq_rotate', length_rotate']
id └───────────────┘ └────────────┘
src └──┘└───────────────┘└┘└────────────┘└─
typ └──┘└───────────────┘└┘└────────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └────────────────────┘└──────────────┘┴└
4788
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4789 lemma rotate_eq_take_append_drop {l : list α} {n : ℕ} : n ≤ l.length →
id └──┘ ┴ ┴ ┴ ┴ ┴└─────┘
src └──┘ ┴ ┴ └─────┘
typ └──┘ ┴ ┴ ┴ ┴ ┴└─────┘
4790 l.rotate n = l.drop n ++ l.take n :=
id ┴└─────┘ ┴ ┴ ┴└───┘ ┴ └┘ ┴└───┘ ┴
src └─────┘ ┴ └───┘ └┘ └───┘
typ ┴└─────┘ ┴ ┴ ┴└───┘ ┴ └┘ ┴└───┘ ┴
doc └─────┘
4791 by rw rotate_eq_rotate'; exact rotate'_eq_take_append_drop
id └───────────────┘ └─────────────────────────┘
src └─┘└───────────────┘ └────┘└─────────────────────────┘└
typ └─┘└───────────────┘ └────┘└─────────────────────────┘└
doc └─┘ └────┘ └
txt └─┘ └────┘ └
par └─┘ └────┘ └
pid ┴ ┴ └
st └────────────────────────────────────────────────────────
4792
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4793 lemma rotate_rotate (l : list α) (n m : ℕ) : (l.rotate n).rotate m = l.rotate (n + m) :=
id └──┘ ┴ ┴ ┴└─────┘ ┴ └────┘ ┴ ┴ ┴└─────┘ ┴ ┴ ┴
src └──┘ ┴ └─────┘ └────┘ ┴ └─────┘ ┴
typ └──┘ ┴ ┴ ┴└─────┘ ┴ └────┘ ┴ ┴ ┴└─────┘ ┴ ┴ ┴
doc └─────┘ └────┘ └─────┘
4794 by rw [rotate_eq_rotate', rotate_eq_rotate', rotate_eq_rotate', rotate'_rotate']
id └───────────────┘ └───────────────┘ └───────────────┘ └─────────────┘
src └──┘└───────────────┘└┘└───────────────┘└┘└───────────────┘└┘└─────────────┘└─
typ └──┘└───────────────┘└┘└───────────────┘└┘└───────────────┘└┘└─────────────┘└─
doc └──┘ └┘ └┘ └┘ └─
txt └──┘ └┘ └┘ └┘ └─
par └──┘ └┘ └┘ └┘ └─
pid └┘ └┘ └┘ └┘ ┴└
st └────────────────────┘└─────────────────┘└─────────────────┘└───────────────┘┴└
4795
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4796 @[simp] lemma rotate_length (l : list α) : rotate l l.length = l :=
id └──┘ ┴ └────┘ ┴ ┴└─────┘ ┴ ┴
src └──┘ └────┘ └─────┘ ┴
typ └──┘ ┴ └────┘ ┴ ┴└─────┘ ┴ ┴
doc └──┘ └────┘
4797 by rw [rotate_eq_rotate', rotate'_length]
id └───────────────┘ └────────────┘
src └──┘└───────────────┘└┘└────────────┘└─
typ └──┘└───────────────┘└┘└────────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └────────────────────┘└──────────────┘┴└
4798
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4799 @[simp] lemma rotate_length_mul (l : list α) (n : ℕ) : l.rotate (l.length * n) = l :=
id └──┘ ┴ ┴ ┴└─────┘ ┴└─────┘ ┴ ┴ ┴ ┴
src └──┘ ┴ └─────┘ └─────┘ ┴ ┴
typ └──┘ ┴ ┴ ┴└─────┘ ┴└─────┘ ┴ ┴ ┴ ┴
doc └──┘ └─────┘
4800 by rw [rotate_eq_rotate', rotate'_length_mul]
id └───────────────┘ └────────────────┘
src └──┘└───────────────┘└┘└────────────────┘└─
typ └──┘└───────────────┘└┘└────────────────┘└─
doc └──┘ └┘ └─
txt └──┘ └┘ └─
par └──┘ └┘ └─
pid └┘ └┘ ┴└
st └────────────────────┘└──────────────────┘┴└
4801
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4802 lemma prod_rotate_eq_one_of_prod_eq_one [group α] : ∀ {l : list α} (hl : l.prod = 1) (n : ℕ),
id └───┘ ┴ ┴ └──┘ ┴ ┴└───┘ ┴ ┴
src └───┘ └──┘ └───┘ ┴ ┴
typ └───┘ ┴ ┴ └──┘ ┴ ┴└───┘ ┴ ┴
doc └───┘
4803 (l.rotate n).prod = 1
id ┴└─────┘ ┴ └──┘ ┴
src └─────┘ └──┘ ┴
typ ┴└─────┘ ┴ └──┘ ┴
doc └─────┘ └──┘
4804 | [] _ _ := by simp
id └┘
src └┘ └───┘
typ └┘ └───┘
doc └───┘
txt └───┘
par └───┘
pid ┴
st └────┘
4805 | (a::l) hl n :=
id ┴└┘┴ ┴
src └┘
typ ┴└┘┴ ┴
4806 have n % list.length (a :: l) ≤ list.length (a :: l), from le_of_lt (nat.mod_lt _ dec_trivial),
id ┴ └─────────┘ └┘ ┴ └─────────┘ └┘ └──────┘ └────────┘ └─────────┘
src ┴ └─────────┘ └┘ ┴ └─────────┘ └┘ └──────┘ └────────┘ └─────────┘
typ ┴ └─────────┘ └┘ ┴ └─────────┘ └┘ └──────┘ └────────┘ └─────────┘
doc └─────────┘
4807 by rw ← list.take_append_drop (n % list.length (a :: l)) (a :: l) at hl;
id └───────────────────┘ ┴ ┴ └─────────┘ ┴ ┴
src └───┘└───────────────────┘┴ ┴┴┴└─────────┘┴ ┴ ┴ └─┘ ┴ ┴ └─────┘
typ └───┘└───────────────────┘┴ ┴┴┴┴└─────────┘┴ ┴ ┴ └─┘ ┴┴ ┴┴└─────┘
doc └───┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └─────┘
txt └───┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └─────┘
par └───┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ └─────┘
pid └─┘ ┴ ┴ ┴ ┴ ┴ ┴ └─┘ ┴ ┴ ┴└────┘
st └──────────────────────────────────────────────────────────────────────
4808 rw [← rotate_mod, rotate_eq_take_append_drop this, list.prod_append, mul_eq_one_iff_inv_eq,
id └────────┘ └────────────────────────┘ └──┘ └──────────────┘ └───────────────────┘
src └────┘└────────┘└┘└────────────────────────┘┴ └┘└──────────────┘└┘└───────────────────┘└─
typ └────┘└────────┘└┘└────────────────────────┘┴└──┘└┘└──────────────┘└┘└───────────────────┘└─
doc └────┘ └┘ ┴ └┘ └┘ └─
txt └────┘ └┘ ┴ └┘ └┘ └─
par └────┘ └┘ ┴ └┘ └┘ └─
pid └──┘ └┘ ┴ └┘ └┘ └─
st ─────┘└──────────┘└───────────────────────────────┘└────────────────┘└─────────────────────┘└─
4809 ← one_mul (list.prod _)⁻¹, ← hl, list.prod_append, mul_assoc, mul_inv_self, mul_one]
id └─────┘ └───────┘ └┘ └┘ └──────────────┘ └───────┘ └──────────┘ └─────┘
src ─────┘└─────┘┴ └───────┘└─┘└┘└──┘ └┘└──────────────┘└┘└───────┘└┘└──────────┘└┘└─────┘└─
typ ─────┘└─────┘┴ └───────┘└─┘└┘└──┘└┘└┘└──────────────┘└┘└───────┘└┘└──────────┘└┘└─────┘└─
doc ─────┘ ┴ └───────┘└─┘ └──┘ └┘ └┘ └┘ └┘ └─
txt ─────┘ ┴ └─┘ └──┘ └┘ └┘ └┘ └┘ └─
par ─────┘ ┴ └─┘ └──┘ └┘ └┘ └┘ └┘ └─
pid ─────┘ ┴ └─┘ └──┘ └┘ └┘ └┘ └┘ ┴└
st ────────────────────────────┘└────┘└────────────────┘└─────────┘└────────────┘└───────┘┴└
4810
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4811 section choose
4812 variables (p : α → Prop) [decidable_pred p] (l : list α)
id └────────────┘ └──┘
src └────────────┘ └──┘
typ └────────────┘ └──┘
4813
4814 lemma choose_spec (hp : ∃ a, a ∈ l ∧ p a) : choose p l hp ∈ l ∧ p (choose p l hp) :=
id ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘
src ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └────┘
typ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘
4815 (choose_x p l hp).property
id └──────┘ ┴ ┴ └┘ └──────┘
src └──────┘ └──────┘
typ └──────┘ ┴ ┴ └┘ └──────┘
4816
4817 lemma choose_mem (hp : ∃ a, a ∈ l ∧ p a) : choose p l hp ∈ l := (choose_spec _ _ _).1
id ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ └─────────┘ ┴
src ┴ ┴ ┴ ┴ └────┘ ┴ └─────────┘ ┴
typ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ ┴ ┴ └─────────┘ ┴
4818
4819 lemma choose_property (hp : ∃ a, a ∈ l ∧ p a) : p (choose p l hp) := (choose_spec _ _ _).2
id ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ └─────────┘ ┴
src ┴ ┴ ┴ ┴ └────┘ └─────────┘ ┴
typ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴ ┴ ┴ └────┘ ┴ ┴ └┘ └─────────┘ ┴
4820
4821 end choose
4822
4823
4824 namespace func
4825
4826 variables {a : α}
4827 variables {as as1 as2 as3 : list α}
id └──┘
src └──┘
typ └──┘
4828
4829 localized "notation as ` {` m ` ↦ ` a `}` := list.func.set a as m" in list.func
4830
4831 /- set -/
4832
4833 lemma length_set [inhabited α] : ∀ {m : ℕ} {as : list α},
id └───────┘ ┴ ┴ ┴ └──┘ ┴
src └───────┘ ┴ └──┘
typ └───────┘ ┴ ┴ ┴ └──┘ ┴
4834 (as {m ↦ a}).length = _root_.max as.length (m+1)
id └┘ ┴┴ ┴ ┴┴ └────┘ ┴ └────────┘ └┘└─────┘ ┴┴
src ┴ ┴ ┴ └────┘ ┴ └────────┘ └─────┘ ┴
typ └┘ ┴┴ ┴ ┴┴ └────┘ ┴ └────────┘ └┘└─────┘ ┴┴
4835 | 0 [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
4836 | 0 (a::as) := by {rw max_eq_left, refl, simp [nat.le_add_right]}
id └┘ └─────────┘ └──────────────┘
src └┘ └─┘└─────────┘ └──┘ └────┘└──────────────┘┴
typ └┘ └─┘└─────────┘ └──┘ └────┘└──────────────┘┴
doc └─┘ └──┘ └────┘ ┴
txt └─┘ └──┘ └────┘ ┴
par └─┘ └──┘ └────┘ ┴
pid ┴ ┴┴ ┴
st └──────────────┘└────┘└───────────────────────┘└┘
4837 | (m+1) [] := by simp only [set, nat.zero_max, length, @length_set m]
id ┴ └┘ └─┘ └──────────┘ └────┘ └────────┘ ┴
src ┴ └┘ └─────────┘└─┘└┘└──────────┘└┘└────┘└┘ ┴ └┘
typ ┴ └┘ └─────────┘└─┘└┘└──────────┘└┘└────┘└┘ └────────┘┴┴└┘
doc └─────────┘ └┘ └┘ └┘ ┴ └┘
txt └─────────┘ └┘ └┘ └┘ ┴ └┘
par └─────────┘ └┘ └┘ └┘ ┴ └┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ ┴┴
st └────────────────────────────────────────────────────┘
4838 | (m+1) (a::as) := by simp only [set, nat.max_succ_succ, length, @length_set m]
id ┴ └┘ └─┘ └───────────────┘ └────┘ └────────┘ ┴
src ┴ └┘ └─────────┘└─┘└┘└───────────────┘└┘└────┘└┘ ┴ └─
typ ┴ └┘ └─────────┘└─┘└┘└───────────────┘└┘└────┘└┘ └────────┘┴┴└─
doc └─────────┘ └┘ └┘ └┘ ┴ └─
txt └─────────┘ └┘ └┘ └┘ ┴ └─
par └─────────┘ └┘ └┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ └┘ ┴ ┴└
st └──────────────────────────────────────────────────────────
4839
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4840 @[simp] lemma get_nil [inhabited α] {k : ℕ} : get k [] = default α :=
id └───────┘ ┴ ┴ └─┘ ┴ └┘ ┴ └─────┘ ┴
src └───────┘ ┴ └─┘ └┘ ┴ └─────┘
typ └───────┘ ┴ ┴ └─┘ ┴ └┘ ┴ └─────┘ ┴
doc └──┘
4841 by {cases k; refl}
id ┴
src └────┘ └──┘
typ └────┘┴ └──┘
doc └────┘ └──┘
txt └────┘ └──┘
par └────┘ └──┘
pid ┴
st └─────────────┘└┘
4842
4843 lemma get_eq_default_of_le [inhabited α] :
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
4844 ∀ (k : ℕ) {as : list α}, as.length ≤ k → get k as = default α
id ┴ ┴ └──┘ ┴ └┘└─────┘ ┴ ┴ └─┘ ┴ └┘ ┴ └─────┘ ┴
src ┴ └──┘ └─────┘ ┴ └─┘ ┴ └─────┘
typ ┴ ┴ └──┘ ┴ └┘└─────┘ ┴ ┴ └─┘ ┴ └┘ ┴ └─────┘ ┴
4845 | 0 [] h1 := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
4846 | 0 (a::as) h1 := by cases h1
id └┘ └┘
src └┘ └────┘ ┴
typ └┘ └────┘└┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st └────────┘
4847 | (k+1) [] h1 := rfl
id ┴ └┘ └─┘
src ┴ └┘ └─┘
typ ┴ └┘ └─┘
4848 | (k+1) (a::as) h1 :=
id ┴ └┘
src ┴ └┘
typ ┴ └┘
4849 begin
st └─────
4850 apply get_eq_default_of_le k,
id └──────────────────┘ ┴
src └────┘ ┴
typ └────┘└──────────────────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───────────────────────────────┘└─
4851 rw ← nat.succ_le_succ_iff, apply h1,
id └──────────────────┘
src └───┘└──────────────────┘ └────┘
typ └───┘└──────────────────┘ └────┘
doc └───┘ └────┘
txt └───┘ └────┘
par └───┘ └────┘
pid └─┘ ┴
st ────────────────────────────┘└────────┘└─
4852 end
st ────┘
4853
4854 @[simp] lemma get_set [inhabited α] {a : α} :
id └───────┘ ┴ ┴
src └───────┘
typ └───────┘ ┴ ┴
doc └──┘
4855 ∀ {k : ℕ} {as : list α}, get k (as {k ↦ a}) = a
id ┴ ┴ └──┘ ┴ └─┘ ┴ └┘ ┴┴ ┴ ┴┴ ┴ ┴
src ┴ └──┘ └─┘ ┴ ┴ ┴ ┴
typ ┴ ┴ └──┘ ┴ └─┘ ┴ └┘ ┴┴ ┴ ┴┴ ┴ ┴
4856 | 0 as := by {cases as; refl, }
id └┘
src └────┘ └──┘
typ └────┘└┘ └──┘
doc └────┘ └──┘
txt └────┘ └──┘
par └────┘ └──┘
pid ┴
st └──────────────┘└──┘
4857 | (k+1) as := by {cases as; simp [get_set]}
id ┴ └┘
src ┴ └────┘ └────┘ ┴
typ ┴ └────┘└┘ └────┘└─────┘┴
doc └────┘ └────┘ ┴
txt └────┘ └────┘ ┴
par └────┘ └────┘ ┴
pid ┴ ┴┴ ┴
st └────────────────────────┘└┘
4858
4859 lemma eq_get_of_mem [inhabited α] {a : α} :
id └───────┘ ┴ ┴
src └───────┘
typ └───────┘ ┴ ┴
4860 ∀ {as : list α}, a ∈ as → ∃ n : nat, ∀ d : α, a = (get n as)
id ┴ └──┘ ┴ ┴ ┴ └┘ ┴ └─┘┴ ┴ ┴ ┴ └─┘ ┴ └┘
src └──┘ ┴ ┴ └─┘┴ ┴ └─┘
typ ┴ └──┘ ┴ ┴ ┴ └┘ ┴ └─┘┴ ┴ ┴ ┴ └─┘ ┴ └┘
4861 | [] h := by cases h
id └┘ ┴
src └┘ └────┘ ┴
typ └┘ └────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st └───────┘
4862 | (b::as) h :=
id └┘
src └┘
typ └┘
4863 begin
st └─────
4864 rw mem_cons_iff at h, cases h,
id └──────────┘ ┴
src └─┘└──────────┘└───┘ └────┘
typ └─┘└──────────┘└───┘ └────┘┴
doc └─┘ └───┘ └────┘
txt └─┘ └───┘ └────┘
par └─┘ └───┘ └────┘
pid ┴ └───┘ ┴
st ───────────────────────┘└───────┘└─
4865 { existsi 0, intro d, apply h },
src └───────┘ └─────┘ └────┘ ┴
typ └───────┘ └─────┘ └────┘ ┴
doc └───────┘ └─────┘ └────┘ ┴
txt └───────┘ └─────┘ └────┘ ┴
par └───────┘ └─────┘ └────┘ ┴
pid ┴┴ └┘ ┴ ┴
st ─────┘└───────┘└───────┘└────────┘└┘└
4866 { cases eq_get_of_mem h with n h2,
id └───────────┘ ┴
src └────┘ ┴ └────────┘
typ └────┘└───────────┘┴┴└────────┘
doc └────┘ ┴ └────────┘
txt └────┘ ┴ └────────┘
par └────┘ ┴ └────────┘
pid ┴ ┴ └────────┘
st ────────────────────────────────────┘└─
4867 existsi (n+1), apply h2 }
id ┴┴
src └──────┘ ┴└┘ └────┘ ┴
typ └──────┘ ┴┴└┘ └────┘ ┴
doc └──────┘ └┘ └────┘ ┴
txt └──────┘ └┘ └────┘ ┴
par └──────┘ └┘ └────┘ ┴
pid ┴ └┘ ┴ ┴
st ──────────────────┘└─────────┘└─
4868 end
st ────┘
4869
4870 lemma mem_get_of_le [inhabited α] :
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
4871 ∀ {n : ℕ} {as : list α}, n < as.length → get n as ∈ as
id ┴ ┴ └──┘ ┴ ┴ ┴ └┘└─────┘ └─┘ ┴ └┘ ┴ └┘
src ┴ └──┘ ┴ └─────┘ └─┘ ┴
typ ┴ ┴ └──┘ ┴ ┴ ┴ └┘└─────┘ └─┘ ┴ └┘ ┴ └┘
4872 | _ [] h1 := by cases h1
id └┘ └┘
src └┘ └────┘ ┴
typ └┘ └────┘└┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st └────────┘
4873 | 0 (a::as) _ := or.inl rfl
id └┘ └────┘ └─┘
src └┘ └────┘ └─┘
typ └┘ └────┘ └─┘
4874 | (n+1) (a::as) h1 :=
id ┴ └┘
src ┴ └┘
typ ┴ └┘
4875 begin
st └─────
4876 apply or.inr, unfold get,
id └────┘
src └────┘└────┘ └────────┘
typ └────┘└────┘ └────────┘
doc └────┘ └────────┘
txt └────┘ └────────┘
par └────┘ └────────┘
pid ┴ └──┘
st ───────────────┘└──────────┘└─
4877 apply mem_get_of_le,
src └────┘
typ └────┘
doc └────┘
txt └────┘
par └────┘
pid ┴
st ──────────────────────┘└─
4878 apply nat.lt_of_succ_lt_succ h1,
id └────────────────────┘ └┘
src └────┘└────────────────────┘┴
typ └────┘└────────────────────┘┴└┘
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ──────────────────────────────────┘└─
4879 end
st ────┘
4880
4881 lemma mem_get_of_ne_zero [inhabited α] :
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
4882 ∀ {n : ℕ} {as : list α},
id ┴ ┴ └──┘ ┴
src ┴ └──┘
typ ┴ ┴ └──┘ ┴
4883 get n as ≠ default α → get n as ∈ as
id └─┘ ┴ └┘ ┴ └─────┘ ┴ └─┘ ┴ └┘ ┴ └┘
src └─┘ ┴ └─────┘ └─┘ ┴
typ └─┘ ┴ └┘ ┴ └─────┘ ┴ └─┘ ┴ └┘ ┴ └┘
4884 | _ [] h1 := begin exfalso, apply h1, rw get_nil end
id └┘ └─────┘
src └┘ └─────┘ └────┘ └─┘└─────┘┴
typ └┘ └─────┘ └────┘ └─┘└─────┘┴
doc └─────┘ └────┘ └─┘ ┴
txt └─────┘ └────┘ └─┘ ┴
par └─────┘ └────┘ └─┘ ┴
pid ┴ ┴ ┴
st └───────────┘└────────┘└───────────┘└─┘
4885 | 0 (a::as) h1 := or.inl rfl
id └┘ └────┘ └─┘
src └┘ └────┘ └─┘
typ └┘ └────┘ └─┘
4886 | (n+1) (a::as) h1 :=
id ┴ └┘
src ┴ └┘
typ ┴ └┘
4887 begin
st └─────
4888 unfold get,
src └────────┘
typ └────────┘
doc └────────┘
txt └────────┘
par └────────┘
pid └──┘
st ─────────────┘└─
4889 apply (or.inr (mem_get_of_ne_zero _)),
id └────┘ └────────────────┘
src └────┘ └────┘┴ └──┘
typ └────┘ └────┘┴ └────────────────┘└──┘
doc └────┘ ┴ └──┘
txt └────┘ ┴ └──┘
par └────┘ ┴ └──┘
pid ┴ ┴ └──┘
st ────────────────────────────────────────┘└─
4890 apply h1
src └────┘ └
typ └────┘ └
doc └────┘ └
txt └────┘ └
par └────┘ └
pid ┴ └
st ─────────────
4891 end
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
4892
4893 lemma get_set_eq_of_ne [inhabited α] {a : α} :
id └───────┘ ┴ ┴
src └───────┘
typ └───────┘ ┴ ┴
4894 ∀ {as : list α} (k : ℕ) (m : ℕ),
id ┴ └──┘ ┴ ┴ ┴
src └──┘ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴
4895 m ≠ k → get m (as {k ↦ a}) = get m as
id ┴ ┴ ┴ └─┘ ┴ └┘ ┴┴ ┴ ┴┴ ┴ └─┘ ┴ └┘
src ┴ └─┘ ┴ ┴ ┴ ┴ └─┘
typ ┴ ┴ ┴ └─┘ ┴ └┘ ┴┴ ┴ ┴┴ ┴ └─┘ ┴ └┘
4896 | as 0 m h1 :=
4897 by { cases m, contradiction, cases as;
id ┴ └┘
src └────┘ └───────────┘ └────┘
typ └────┘┴ └───────────┘ └────┘└┘
doc └────┘ └───────────┘ └────┘
txt └────┘ └───────────┘ └────┘
par └────┘ └───────────┘ └────┘
pid ┴ ┴
st └────────┘└─────────────┘└───────────
4898 simp only [set, get, get_nil] }
id └─┘ └─┘ └─────┘
src └─────────┘└─┘└┘└─┘└┘└─────┘└┘
typ └─────────┘└─┘└┘└─┘└┘└─────┘└┘
doc └─────────┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ ┴┴
st ────────────────────────────────────┘└┘
4899 | as (k+1) m h1 :=
id ┴
src ┴
typ ┴
4900 begin
st └─────
4901 cases as; cases m,
id └┘ ┴
src └────┘ └────┘
typ └────┘└┘ └────┘┴
doc └────┘ └────┘
txt └────┘ └────┘
par └────┘ └────┘
pid ┴ ┴
st ────────────────────┘└─
4902 simp only [set, get],
id └─┘ └─┘
src └─────────┘└─┘└┘└─┘┴
typ └─────────┘└─┘└┘└─┘┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st ───────────────────────┘└─
4903 { have h3 : get m (nil {k ↦ a}) = default α,
id └─┘ ┴ └─┘ ┴ ┴ ┴ └─────┘ ┴
src └────────┘└─┘┴ ┴ └─┘┴ ┴ ┴ └┘┴┴└─────┘┴
typ └────────┘└─┘┴┴┴ └─┘┴ ┴┴ ┴┴ └┘┴┴└─────┘┴┴
doc └────────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴
txt └────────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴
par └────────┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴
pid └─────┘└─┘ ┴ ┴ ┴ ┴ ┴ └┘ ┴ ┴
st ─────┘└───────────────────────────────────────┘└─
4904 { rw [get_set_eq_of_ne k m, get_nil],
id └──────────────┘ ┴ ┴ └─────┘
src └──┘ ┴ ┴ └┘└─────┘┴
typ └──┘└──────────────┘┴┴┴┴└┘└─────┘┴
doc └──┘ ┴ ┴ └┘ ┴
txt └──┘ ┴ ┴ └┘ ┴
par └──┘ ┴ ┴ └┘ ┴
pid └┘ ┴ ┴ └┘ ┴
st ───────┘└──────────────────────┘└───────┘└──
4905 intro hc, apply h1, simp [hc] },
id └┘
src └──────┘ └────┘ └────┘ └┘
typ └──────┘ └────┘ └────┘└┘└┘
doc └──────┘ └────┘ └────┘ └┘
txt └──────┘ └────┘ └────┘ └┘
par └──────┘ └────┘ └────┘ └┘
pid └─┘ ┴ ┴┴ ┴┴
st ───────────────┘└────────┘└──────────┘└┘└
4906 apply h3 },
src └────┘ ┴
typ └────┘ ┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ──────────────┘└┘└
4907 simp only [set, get],
id └─┘ └─┘
src └─────────┘└─┘└┘└─┘┴
typ └─────────┘└─┘└┘└─┘┴
doc └─────────┘ └┘ ┴
txt └─────────┘ └┘ ┴
par └─────────┘ └┘ ┴
pid ┴└──┘└┘ └┘ ┴
st ───────────────────────┘└─
4908 { apply get_set_eq_of_ne k m,
id └──────────────┘ ┴ ┴
src └────┘ ┴ ┴
typ └────┘└──────────────┘┴┴┴┴
doc └────┘ ┴ ┴
txt └────┘ ┴ ┴
par └────┘ ┴ ┴
pid ┴ ┴ ┴
st ───────────────────────────────┘└─
4909 intro hc, apply h1, simp [hc], }
id └┘
src └──────┘ └────┘ └────┘ ┴
typ └──────┘ └────┘ └────┘└┘┴
doc └──────┘ └────┘ └────┘ ┴
txt └──────┘ └────┘ └────┘ ┴
par └──────┘ └────┘ └────┘ ┴
pid └─┘ ┴ ┴┴ ┴
st ─────────────┘└────────┘└─────────┘└───
4910 end
st ────┘
4911
4912 lemma get_map [inhabited α] [inhabited β] {f : α → β} :
id └───────┘ ┴ └───────┘ ┴ ┴ ┴
src └───────┘ └───────┘
typ └───────┘ ┴ └───────┘ ┴ ┴ ┴
4913 ∀ {n : ℕ} {as : list α}, n < as.length →
id ┴ ┴ └──┘ ┴ ┴ ┴ └┘└─────┘
src ┴ └──┘ ┴ └─────┘
typ ┴ ┴ └──┘ ┴ ┴ ┴ └┘└─────┘
4914 get n (as.map f) = f (get n as)
id └─┘ ┴ └┘└──┘ ┴ ┴ ┴ └─┘ ┴ └┘
src └─┘ └──┘ ┴ └─┘
typ └─┘ ┴ └┘└──┘ ┴ ┴ ┴ └─┘ ┴ └┘
4915 | _ [] h := by cases h
id └┘ ┴
src └┘ └────┘ ┴
typ └┘ └────┘┴┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st └───────┘
4916 | 0 (a::as) h := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
4917 | (n+1) (a::as) h1 :=
id ┴ └┘
src ┴ └┘
typ ┴ └┘
4918 begin
st └─────
4919 have h2 : n < length as,
id ┴ ┴ └────┘ └┘
src └────────┘ ┴┴┴└────┘┴
typ └────────┘┴┴┴┴└────┘┴└┘
doc └────────┘ ┴ ┴ ┴
txt └────────┘ ┴ ┴ ┴
par └────────┘ ┴ ┴ ┴
pid └─────┘└─┘ ┴ ┴ ┴
st ──────────────────────────┘└─
4920 { rw [← nat.succ_le_iff, ← nat.lt_succ_iff],
id └─────────────┘ └─────────────┘
src └────┘└─────────────┘└──┘└─────────────┘┴
typ └────┘└─────────────┘└──┘└─────────────┘┴
doc └────┘ └──┘ ┴
txt └────┘ └──┘ ┴
par └────┘ └──┘ ┴
pid └──┘ └──┘ ┴
st ─────┘└───────────────────┘└─────────────────┘└──
4921 apply h1 },
src └────┘ ┴
typ └────┘ ┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ──────────────┘└┘└
4922 apply get_map h2,
id └─────┘ └┘
src └────┘ ┴
typ └────┘└─────┘┴└┘
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───────────────────┘└─
4923 end
st ────┘
4924
4925 lemma get_map' [inhabited α] [inhabited β]
id └───────┘ ┴ └───────┘ ┴
src └───────┘ └───────┘
typ └───────┘ ┴ └───────┘ ┴
4926 {f : α → β} {n : ℕ} {as : list α} :
id ┴ ┴ ┴ └──┘ ┴
src ┴ └──┘
typ ┴ ┴ ┴ └──┘ ┴
4927 f (default α) = (default β) →
id ┴ └─────┘ ┴ ┴ └─────┘ ┴
src └─────┘ ┴ └─────┘
typ ┴ └─────┘ ┴ ┴ └─────┘ ┴
4928 get n (as.map f) = f (get n as) :=
id └─┘ ┴ └┘└──┘ ┴ ┴ ┴ └─┘ ┴ └┘
src └─┘ └──┘ ┴ └─┘
typ └─┘ ┴ └┘└──┘ ┴ ┴ ┴ └─┘ ┴ └┘
4929 begin
st └─────
4930 intro h1, by_cases h2 : n < as.length,
id ┴ ┴ └───────┘
src └──────┘ └───────┘ └─┘ ┴┴┴└───────┘
typ └──────┘ └───────┘ └─┘┴┴┴┴└───────┘
doc └──────┘ └───────┘ └─┘ ┴ ┴
txt └──────┘ └───────┘ └─┘ ┴ ┴
par └──────┘ └───────┘ └─┘ ┴ ┴
pid └─┘ ┴ └─┘ ┴ ┴
st ─────────┘└───────────────────────────┘└─
4931 { apply get_map h2, },
id └─────┘ └┘
src └────┘└─────┘┴
typ └────┘└─────┘┴└┘
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───┘└──────────────┘└──┘└
4932 { rw not_lt at h2,
id └────┘
src └─┘└────┘└────┘
typ └─┘└────┘└────┘
doc └─┘ └────┘
txt └─┘ └────┘
par └─┘ └────┘
pid ┴ └────┘
st ──────────────────┘└─
4933 rw [get_eq_default_of_le _ h2, get_eq_default_of_le, h1],
id └──────────────────┘ └┘ └──────────────────┘ └┘
src └──┘└──────────────────┘└─┘ └┘└──────────────────┘└┘ ┴
typ └──┘└──────────────────┘└─┘└┘└┘└──────────────────┘└┘└┘┴
doc └──┘ └─┘ └┘ └┘ ┴
txt └──┘ └─┘ └┘ └┘ ┴
par └──┘ └─┘ └┘ └┘ ┴
pid └┘ └─┘ └┘ └┘ ┴
st ────────────────────────────────┘└────────────────────┘└──┘└──
4934 rw [length_map], apply h2 }
id └────────┘
src └──┘└────────┘┴ └────┘ ┴
typ └──┘└────────┘┴ └────┘ ┴
doc └──┘ ┴ └────┘ ┴
txt └──┘ ┴ └────┘ ┴
par └──┘ ┴ └────┘ ┴
pid └┘ ┴ ┴ ┴
st ─────────────────┘└──────────┘└─
4935 end
st ──┘
4936
4937 lemma forall_val_of_forall_mem [inhabited α]
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
4938 {as : list α} {p : α → Prop} :
id └──┘ ┴ ┴
src └──┘
typ └──┘ ┴ ┴
4939 p (default α) → (∀ x ∈ as, p x) → (∀ n, p (get n as)) :=
id ┴ └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └─┘ ┴ └┘
src └─────┘ └─┘
typ ┴ └─────┘ ┴ ┴ └┘ ┴ ┴ ┴ ┴ └─┘ ┴ └┘
4940 begin
st └─────
4941 intros h1 h2 n,
src └────────────┘
typ └────────────┘
doc └────────────┘
txt └────────────┘
par └────────────┘
pid └──────┘
st ───────────────┘└─
4942 by_cases h3 : n < as.length,
id ┴ ┴ └───────┘
src └───────┘ └─┘ ┴┴┴└───────┘
typ └───────┘ └─┘┴┴┴┴└───────┘
doc └───────┘ └─┘ ┴ ┴
txt └───────┘ └─┘ ┴ ┴
par └───────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ────────────────────────────┘└─
4943 { apply h2 _ (mem_get_of_le h3) },
id └┘ └───────────┘ └┘
src └────┘ └─┘ └───────────┘┴ └┘
typ └────┘└┘└─┘ └───────────┘┴└┘└┘
doc └────┘ └─┘ ┴ └┘
txt └────┘ └─┘ ┴ └┘
par └────┘ └─┘ ┴ └┘
pid ┴ └─┘ ┴ ┴┴
st ───┘└────────────────────────────┘└┘└
4944 { rw not_lt at h3,
id └────┘
src └─┘└────┘└────┘
typ └─┘└────┘└────┘
doc └─┘ └────┘
txt └─┘ └────┘
par └─┘ └────┘
pid ┴ └────┘
st ──────────────────┘└─
4945 rw get_eq_default_of_le _ h3, apply h1 }
id └──────────────────┘ └┘
src └─┘└──────────────────┘└─┘ └────┘ ┴
typ └─┘└──────────────────┘└─┘└┘ └────┘ ┴
doc └─┘ └─┘ └────┘ ┴
txt └─┘ └─┘ └────┘ ┴
par └─┘ └─┘ └────┘ ┴
pid ┴ └─┘ ┴ ┴
st ───────────────────────────────┘└─────────┘└─
4946 end
st ──┘
4947
4948 /- equiv -/
4949
4950 lemma equiv_refl [inhabited α] : equiv as as := λ k, rfl
id └───────┘ ┴ └───┘ └┘ └┘ ┴ └─┘
src └───────┘ └───┘ └─┘
typ └───────┘ ┴ └───┘ └┘ └┘ ┴ └─┘
4951
4952 lemma equiv_symm [inhabited α] : equiv as1 as2 → equiv as2 as1 :=
id └───────┘ ┴ └───┘ └─┘ └─┘ └───┘ └─┘ └─┘
src └───────┘ └───┘ └───┘
typ └───────┘ ┴ └───┘ └─┘ └─┘ └───┘ └─┘ └─┘
4953 λ h1 k, (h1 k).symm
id └┘ ┴ └┘ ┴ └──┘
src └──┘
typ └┘ ┴ └┘ ┴ └──┘
4954
4955 lemma equiv_trans [inhabited α] :
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
4956 equiv as1 as2 → equiv as2 as3 → equiv as1 as3 :=
id └───┘ └─┘ └─┘ └───┘ └─┘ └─┘ └───┘ └─┘ └─┘
src └───┘ └───┘ └───┘
typ └───┘ └─┘ └─┘ └───┘ └─┘ └─┘ └───┘ └─┘ └─┘
4957 λ h1 h2 k, eq.trans (h1 k) (h2 k)
id └┘ └┘ ┴ └──────┘ └┘ ┴ └┘ ┴
src └──────┘
typ └┘ └┘ ┴ └──────┘ └┘ ┴ └┘ ┴
4958
4959 lemma equiv_of_eq [inhabited α] : as1 = as2 → equiv as1 as2 :=
id └───────┘ ┴ └─┘ ┴ └─┘ └───┘ └─┘ └─┘
src └───────┘ ┴ └───┘
typ └───────┘ ┴ └─┘ ┴ └─┘ └───┘ └─┘ └─┘
4960 begin intro h1, rw h1, apply equiv_refl end
id └┘ └────────┘
src └──────┘ └─┘ └────┘└────────┘┴
typ └──────┘ └─┘└┘ └────┘└────────┘┴
doc └──────┘ └─┘ └────┘ ┴
txt └──────┘ └─┘ └────┘ ┴
par └──────┘ └─┘ └────┘ ┴
pid └─┘ ┴ ┴ ┴
st └────────────┘└─────┘└─────────────────┘└─┘
4961
4962 lemma eq_of_equiv [inhabited α] :
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
4963 ∀ {as1 as2 : list α}, as1.length = as2.length →
id ┴ └──┘ ┴ └─┘└─────┘ ┴ └─┘└─────┘
src └──┘ └─────┘ ┴ └─────┘
typ ┴ └──┘ ┴ └─┘└─────┘ ┴ └─┘└─────┘
4964 equiv as1 as2 → as1 = as2
id └───┘ └─┘ └─┘ └─┘ ┴ └─┘
src └───┘ ┴
typ └───┘ └─┘ └─┘ └─┘ ┴ └─┘
4965 | [] [] h1 h2 := rfl
id └┘ └┘ └─┘
src └┘ └┘ └─┘
typ └┘ └┘ └─┘
4966 | (_::_) [] h1 h2 := by cases h1
id └┘ └┘ └┘
src └┘ └┘ └────┘ ┴
typ └┘ └┘ └────┘└┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st └────────┘
4967 | [] (_::_) h1 h2 := by cases h1
id └┘ └┘ └┘
src └┘ └┘ └────┘ ┴
typ └┘ └┘ └────┘└┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st └────────┘
4968 | (a1::as1) (a2::as2) h1 h2 :=
id └┘ └┘
src └┘ └┘
typ └┘ └┘
4969 begin
st └─────
4970 congr,
src └───┘
typ └───┘
txt └───┘
par └───┘
st ────────┘└─
4971 { apply h2 0 },
id └┘
src └────┘ └─┘
typ └────┘└┘└─┘
doc └────┘ └─┘
txt └────┘ └─┘
par └────┘ └─┘
pid ┴ ┴└┘
st ─────┘└─────────┘└┘└
4972 have h3 : as1.length = as2.length,
id └────────┘ ┴ └────────┘
src └────────┘└────────┘┴┴┴└────────┘
typ └────────┘└────────┘┴┴┴└────────┘
doc └────────┘ ┴ ┴
txt └────────┘ ┴ ┴
par └────────┘ ┴ ┴
pid └─────┘└─┘ ┴ ┴
st ────────────────────────────────────┘└─
4973 { simpa [add_left_inj, add_comm, length] using h1 },
id └──────────┘ └──────┘ └────┘ └┘
src └─────┘└──────────┘└┘└──────┘└┘└────┘└──────┘ ┴
typ └─────┘└──────────┘└┘└──────┘└┘└────┘└──────┘└┘┴
doc └─────┘ └┘ └┘ └──────┘ ┴
txt └─────┘ └┘ └┘ └──────┘ ┴
par └─────┘ └┘ └┘ └──────┘ ┴
pid ┴┴ └┘ └┘ ┴┴└────┘ ┴
st ─────┘└──────────────────────────────────────────────┘└┘└
4974 apply eq_of_equiv h3,
id └─────────┘ └┘
src └────┘ ┴
typ └────┘└─────────┘┴└┘
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ───────────────────────┘└─
4975 intro m, apply h2 (m+1)
id └┘ ┴┴
src └─────┘ └────┘ ┴ ┴└──
typ └─────┘ └────┘└┘┴ ┴┴└──
doc └─────┘ └────┘ ┴ └──
txt └─────┘ └────┘ ┴ └──
par └─────┘ └────┘ ┴ └──
pid └┘ ┴ ┴ └┘└
st ──────────┘└────────────────
4976 end
src ─┘
typ ─┘
doc ─┘
txt ─┘
par ─┘
pid ─┘
st ─┘└─┘
4977
4978 /- neg -/
4979
4980 @[simp] lemma get_neg [inhabited α] [add_group α]
id └───────┘ ┴ └───────┘ ┴
src └───────┘ └───────┘
typ └───────┘ ┴ └───────┘ ┴
doc └──┘
4981 {k : ℕ} {as : list α} : @get α ⟨0⟩ k (neg as) = -(@get α ⟨0⟩ k as) :=
id ┴ └──┘ ┴ └─┘ ┴ ┴ └─┘ └┘ ┴ ┴ └─┘ ┴ ┴ └┘
src ┴ └──┘ └─┘ └─┘ ┴ ┴ └─┘
typ ┴ └──┘ ┴ └─┘ ┴ ┴ └─┘ └┘ ┴ ┴ └─┘ ┴ ┴ └┘
4982 by {unfold neg, rw (@get_map' α α ⟨0⟩), apply neg_zero}
id └──────┘ ┴ └──────┘
src └────────┘ └─┘ └──────┘┴ ┴ ┴ └─┘ └────┘└──────┘
typ └────────┘ └─┘ └──────┘┴ ┴┴┴ └─┘ └────┘└──────┘
doc └────────┘ └─┘ ┴ ┴ ┴ └─┘ └────┘
txt └────────┘ └─┘ ┴ ┴ ┴ └─┘ └────┘
par └────────┘ └─┘ ┴ ┴ ┴ └─┘ └────┘
pid └──┘ ┴ ┴ ┴ ┴ └─┘ ┴
st └──────────┘└──────────────────────┘└──────────────┘└┘
4983
4984 @[simp] lemma length_neg
doc └──┘
4985 [inhabited α] [has_neg α] (as : list α) :
id └───────┘ ┴ └─────┘ ┴ └──┘ ┴
src └───────┘ └─────┘ └──┘
typ └───────┘ ┴ └─────┘ ┴ └──┘ ┴
4986 (neg as).length = as.length :=
id └─┘ └┘ └────┘ ┴ └┘└─────┘
src └─┘ └────┘ ┴ └─────┘
typ └─┘ └┘ └────┘ ┴ └┘└─────┘
4987 by simp only [neg, length_map]
id └─┘ └────────┘
src └─────────┘└─┘└┘└────────┘└─
typ └─────────┘└─┘└┘└────────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ ┴└
st └────────────────────────────
4988
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
4989 /- pointwise -/
src ────────────────
typ ────────────────
doc ────────────────
txt ────────────────
par ────────────────
pid ────────────────
st ────────────────
4990
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4991 lemma nil_pointwise [inhabited α] [inhabited β] {f : α → β → γ} :
id └───────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
src └───────┘ └───────┘
typ └───────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
4992 ∀ bs : list β, pointwise f [] bs = bs.map (f $ default α)
id └┘ └──┘ ┴ └───────┘ ┴ └┘ └┘ ┴ └┘└──┘ ┴ └─────┘ ┴
src └──┘ └───────┘ └┘ ┴ └──┘ └─────┘
typ └┘ └──┘ ┴ └───────┘ ┴ └┘ └┘ ┴ └┘└──┘ ┴ └─────┘ ┴
4993 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
4994 | (b::bs) :=
id └┘
src └┘
typ └┘
4995 by simp only [nil_pointwise bs, pointwise,
id └───────────┘ └┘ └───────┘
src └─────────┘ ┴ └┘└───────┘└─
typ └─────────┘└───────────┘┴└┘└┘└───────┘└─
doc └─────────┘ ┴ └┘ └─
txt └─────────┘ ┴ └┘ └─
par └─────────┘ ┴ └┘ └─
pid ┴└──┘└┘ ┴ └┘ └─
st └────────────────────────────────────────
4996 eq_self_iff_true, and_self, map]
id └──────────────┘ └──────┘ └─┘
src ────┘└──────────────┘└┘└──────┘└┘└─┘└─
typ ────┘└──────────────┘└┘└──────┘└┘└─┘└─
doc ────┘ └┘ └┘ └─
txt ────┘ └┘ └┘ └─
par ────┘ └┘ └┘ └─
pid ────┘ └┘ └┘ ┴└
st ──────────────────────────────────────
4997
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
4998 lemma pointwise_nil [inhabited α] [inhabited β] {f : α → β → γ} :
id └───────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
src └───────┘ └───────┘
typ └───────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
4999 ∀ as : list α, pointwise f as [] = as.map (λ a, f a $ default β)
id └┘ └──┘ ┴ └───────┘ ┴ └┘ └┘ ┴ └┘└──┘ ┴ ┴ ┴ └─────┘ ┴
src └──┘ └───────┘ └┘ ┴ └──┘ └─────┘
typ └┘ └──┘ ┴ └───────┘ ┴ └┘ └┘ ┴ └┘└──┘ ┴ ┴ ┴ └─────┘ ┴
5000 | [] := rfl
id └┘ └─┘
src └┘ └─┘
typ └┘ └─┘
5001 | (a::as) :=
id └┘
src └┘
typ └┘
5002 by simp only [pointwise_nil as, pointwise,
id └───────────┘ └┘ └───────┘
src └─────────┘ ┴ └┘└───────┘└─
typ └─────────┘└───────────┘┴└┘└┘└───────┘└─
doc └─────────┘ ┴ └┘ └─
txt └─────────┘ ┴ └┘ └─
par └─────────┘ ┴ └┘ └─
pid ┴└──┘└┘ ┴ └┘ └─
st └────────────────────────────────────────
5003 eq_self_iff_true, and_self, list.map]
id └──────────────┘ └──────┘ └──────┘
src ────┘└──────────────┘└┘└──────┘└┘└──────┘└─
typ ────┘└──────────────┘└┘└──────┘└┘└──────┘└─
doc ────┘ └┘ └┘ └─
txt ────┘ └┘ └┘ └─
par ────┘ └┘ └┘ └─
pid ────┘ └┘ └┘ ┴└
st ───────────────────────────────────────────
5004
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
5005 lemma get_pointwise [inhabited α] [inhabited β] [inhabited γ]
id └───────┘ ┴ └───────┘ ┴ └───────┘ ┴
src └───────┘ └───────┘ └───────┘
typ └───────┘ ┴ └───────┘ ┴ └───────┘ ┴
5006 {f : α → β → γ} (h1 : f (default α) (default β) = default γ) :
id ┴ ┴ ┴ ┴ └─────┘ ┴ └─────┘ ┴ ┴ └─────┘ ┴
src └─────┘ └─────┘ ┴ └─────┘
typ ┴ ┴ ┴ ┴ └─────┘ ┴ └─────┘ ┴ ┴ └─────┘ ┴
5007 ∀ (k : nat) (as : list α) (bs : list β),
id ┴ └─┘ └──┘ ┴ └──┘ ┴
src └─┘ └──┘ └──┘
typ ┴ └─┘ └──┘ ┴ └──┘ ┴
5008 get k (pointwise f as bs) = f (get k as) (get k bs)
id └─┘ ┴ └───────┘ ┴ └┘ └┘ ┴ ┴ └─┘ ┴ └┘ └─┘ ┴ └┘
src └─┘ └───────┘ ┴ └─┘ └─┘
typ └─┘ ┴ └───────┘ ┴ └┘ └┘ ┴ ┴ └─┘ ┴ └┘ └─┘ ┴ └┘
5009 | k [] [] := by simp only [h1, get_nil, pointwise, get]
id └┘ └┘ └┘ └─────┘ └───────┘ └─┘
src └┘ └┘ └─────────┘ └┘└─────┘└┘└───────┘└┘└─┘└┘
typ └┘ └┘ └─────────┘└┘└┘└─────┘└┘└───────┘└┘└─┘└┘
doc └─────────┘ └┘ └┘ └┘ └┘
txt └─────────┘ └┘ └┘ └┘ └┘
par └─────────┘ └┘ └┘ └┘ └┘
pid ┴└──┘└┘ └┘ └┘ └┘ ┴┴
st └───────────────────────────────────────┘
5010 | 0 [] (b::bs) :=
id └┘ └┘
src └┘ └┘
typ └┘ └┘
5011 by simp only [get_pointwise, get_nil,
id └───────────┘ └─────┘
src └─────────┘ └┘└─────┘└─
typ └─────────┘└───────────┘└┘└─────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ └─
st └───────────────────────────────────
5012 pointwise, get, nat.nat_zero_eq_zero, map]
id └───────┘ └─┘ └──────────────────┘ └─┘
src ─────┘└───────┘└┘└─┘└┘└──────────────────┘└┘└─┘└┘
typ ─────┘└───────┘└┘└─┘└┘└──────────────────┘└┘└─┘└┘
doc ─────┘ └┘ └┘ └┘ └┘
txt ─────┘ └┘ └┘ └┘ └┘
par ─────┘ └┘ └┘ └┘ └┘
pid ─────┘ └┘ └┘ └┘ ┴┴
st ────────────────────────────────────────────────┘
5013 | (k+1) [] (b::bs) :=
id ┴ └┘ └┘
src ┴ └┘ └┘
typ ┴ └┘ └┘
5014 by { have : get k (map (f $ default α) bs) = f (default α) (get k bs),
id └─┘ ┴ ┴ └─────┘ ┴ └─┘ ┴ └┘
src └─────┘ ┴ ┴ └─┘┴ ┴ ┴ ┴ └┘ └┘┴┴ ┴ └─────┘┴ └┘ └─┘┴ ┴ ┴
typ └─────┘ ┴ ┴ └─┘┴ ┴ ┴ ┴ └┘ └┘┴┴┴┴ └─────┘┴┴└┘ └─┘┴┴┴└┘┴
doc └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
txt └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
par └─────┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
pid └───┘└┘ ┴ ┴ ┴ ┴ ┴ ┴ └┘ └┘ ┴ ┴ ┴ └┘ ┴ ┴ ┴
st └─────────────────────────────────────────────────────────────────┘└─
5015 { simpa [nil_pointwise, get_nil] using (get_pointwise k [] bs) },
id └───────────┘ └─────┘ └───────────┘ ┴ └┘ └┘
src └─────┘└───────────┘└┘└─────┘└──────┘ ┴ ┴└┘┴ └┘
typ └─────┘└───────────┘└┘└─────┘└──────┘ └───────────┘┴┴┴└┘┴└┘└┘
doc └─────┘ └┘ └──────┘ ┴ ┴ ┴ └┘
txt └─────┘ └┘ └──────┘ ┴ ┴ ┴ └┘
par └─────┘ └┘ └──────┘ ┴ ┴ ┴ └┘
pid ┴┴ └┘ ┴┴└────┘ ┴ ┴ ┴ ┴┴
st ────────┘└───────────────────────────────────────────────────────────┘└┘└
5016 simpa [get, get_nil, pointwise, map] }
id └─┘ └─────┘ └───────┘ └─┘
src └─────┘└─┘└┘└─────┘└┘└───────┘└┘└─┘└┘
typ └─────┘└─┘└┘└─────┘└┘└───────┘└┘└─┘└┘
doc └─────┘ └┘ └┘ └┘ └┘
txt └─────┘ └┘ └┘ └┘ └┘
par └─────┘ └┘ └┘ └┘ └┘
pid ┴┴ └┘ └┘ └┘ ┴┴
st ───────────────────────────────────────────┘└┘
5017 | 0 (a::as) [] :=
id └┘ └┘
src └┘ └┘
typ └┘ └┘
5018 by simp only [get_pointwise, get_nil,
id └───────────┘ └─────┘
src └─────────┘ └┘└─────┘└─
typ └─────────┘└───────────┘└┘└─────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ └─
st └───────────────────────────────────
5019 pointwise, get, nat.nat_zero_eq_zero, map]
id └───────┘ └─┘ └──────────────────┘ └─┘
src ────┘└───────┘└┘└─┘└┘└──────────────────┘└┘└─┘└┘
typ ────┘└───────┘└┘└─┘└┘└──────────────────┘└┘└─┘└┘
doc ────┘ └┘ └┘ └┘ └┘
txt ────┘ └┘ └┘ └┘ └┘
par ────┘ └┘ └┘ └┘ └┘
pid ────┘ └┘ └┘ └┘ ┴┴
st ───────────────────────────────────────────────┘
5020 | (k+1) (a::as) [] :=
id ┴ └┘ └┘
src ┴ └┘ └┘
typ ┴ └┘ └┘
5021 by simpa [get, get_nil, pointwise, map, pointwise_nil, get_nil]
id └─┘ └─────┘ └───────┘ └─┘ └───────────┘ └─────┘
src └─────┘└─┘└┘└─────┘└┘└───────┘└┘└─┘└┘└───────────┘└┘└─────┘└─
typ └─────┘└─┘└┘└─────┘└┘└───────┘└┘└─┘└┘└───────────┘└┘└─────┘└─
doc └─────┘ └┘ └┘ └┘ └┘ └┘ └─
txt └─────┘ └┘ └┘ └┘ └┘ └┘ └─
par └─────┘ └┘ └┘ └┘ └┘ └┘ └─
pid ┴┴ └┘ └┘ └┘ └┘ └┘ ┴└
st └─────────────────────────────────────────────────────────────
5022 using get_pointwise k as []
id └───────────┘ ┴ └┘ └┘
src ──────────┘ ┴ ┴ ┴└┘┴
typ ──────────┘└───────────┘┴┴┴└┘┴└┘┴
doc ──────────┘ ┴ ┴ ┴ ┴
txt ──────────┘ ┴ ┴ ┴ ┴
par ──────────┘ ┴ ┴ ┴ ┴
pid ────┘└────┘ ┴ ┴ ┴ ┴
st ────────────────────────────────┘
5023 | 0 (a::as) (b::bs) := by simp only [pointwise, get]
id └┘ └┘ └───────┘ └─┘
src └┘ └┘ └─────────┘└───────┘└┘└─┘└┘
typ └┘ └┘ └─────────┘└───────┘└┘└─┘└┘
doc └─────────┘ └┘ └┘
txt └─────────┘ └┘ └┘
par └─────────┘ └┘ └┘
pid ┴└──┘└┘ └┘ ┴┴
st └──────────────────────────┘
5024 | (k+1) (a::as) (b::bs) :=
id ┴ └┘ └┘
src ┴ └┘ └┘
typ ┴ └┘ └┘
5025 by simp only [pointwise, get, get_pointwise k]
id └───────┘ └─┘ └───────────┘ ┴
src └─────────┘└───────┘└┘└─┘└┘ ┴ └─
typ └─────────┘└───────┘└┘└─┘└┘└───────────┘┴┴└─
doc └─────────┘ └┘ └┘ ┴ └─
txt └─────────┘ └┘ └┘ ┴ └─
par └─────────┘ └┘ └┘ ┴ └─
pid ┴└──┘└┘ └┘ └┘ ┴ ┴└
st └────────────────────────────────────────────
5026
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
5027 lemma length_pointwise [inhabited α] [inhabited β] {f : α → β → γ} :
id └───────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
src └───────┘ └───────┘
typ └───────┘ ┴ └───────┘ ┴ ┴ ┴ ┴
5028 ∀ {as : list α} {bs : list β},
id ┴ └──┘ ┴ └──┘ ┴
src └──┘ └──┘
typ ┴ └──┘ ┴ └──┘ ┴
5029 (pointwise f as bs).length = _root_.max as.length bs.length
id └───────┘ ┴ └┘ └┘ └────┘ ┴ └────────┘ └┘└─────┘ └┘└─────┘
src └───────┘ └────┘ ┴ └────────┘ └─────┘ └─────┘
typ └───────┘ ┴ └┘ └┘ └────┘ ┴ └────────┘ └┘└─────┘ └┘└─────┘
5030 | [] [] := rfl
id └┘ └┘ └─┘
src └┘ └┘ └─┘
typ └┘ └┘ └─┘
5031 | [] (b::bs) :=
id └┘ └┘
src └┘ └┘
typ └┘ └┘
5032 by simp only [pointwise, length, length_map,
id └───────┘ └────┘ └────────┘
src └─────────┘└───────┘└┘└────┘└┘└────────┘└─
typ └─────────┘└───────┘└┘└────┘└┘└────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └─
st └──────────────────────────────────────────
5033 max_eq_right (nat.zero_le (length bs + 1))]
id └──────────┘ └─────────┘ └────┘ └┘ ┴
src ────┘└──────────┘┴ └─────────┘┴ └────┘┴ ┴┴└────┘
typ ────┘└──────────┘┴ └─────────┘┴ └────┘┴└┘┴┴└────┘
doc ────┘ ┴ ┴ ┴ ┴ └────┘
txt ────┘ ┴ ┴ ┴ ┴ └────┘
par ────┘ ┴ ┴ ┴ ┴ └────┘
pid ────┘ ┴ ┴ ┴ ┴ └───┘┴
st ────────────────────────────────────────────────┘
5034 | (a::as) [] :=
id └┘ └┘
src └┘ └┘
typ └┘ └┘
5035 by simp only [pointwise, length, length_map,
id └───────┘ └────┘ └────────┘
src └─────────┘└───────┘└┘└────┘└┘└────────┘└─
typ └─────────┘└───────┘└┘└────┘└┘└────────┘└─
doc └─────────┘ └┘ └┘ └─
txt └─────────┘ └┘ └┘ └─
par └─────────┘ └┘ └┘ └─
pid ┴└──┘└┘ └┘ └┘ └─
st └──────────────────────────────────────────
5036 max_eq_left (nat.zero_le (length as + 1))]
id └─────────┘ └─────────┘ └────┘ └┘
src ────┘└─────────┘┴ └─────────┘┴ └────┘┴ ┴ └────┘
typ ────┘└─────────┘┴ └─────────┘┴ └────┘┴└┘┴ └────┘
doc ────┘ ┴ ┴ ┴ ┴ └────┘
txt ────┘ ┴ ┴ ┴ ┴ └────┘
par ────┘ ┴ ┴ ┴ ┴ └────┘
pid ────┘ ┴ ┴ ┴ ┴ └───┘┴
st ───────────────────────────────────────────────┘
5037 | (a::as) (b::bs) :=
id └┘ └┘
src └┘ └┘
typ └┘ └┘
5038 by simp only [pointwise, length,
id └───────┘ └────┘
src └─────────┘└───────┘└┘└────┘└─
typ └─────────┘└───────┘└┘└────┘└─
doc └─────────┘ └┘ └─
txt └─────────┘ └┘ └─
par └─────────┘ └┘ └─
pid ┴└──┘└┘ └┘ └─
st └──────────────────────────────
5039 nat.max_succ_succ, @length_pointwise as bs]
id └───────────────┘ └──────────────┘ └┘ └┘
src ────┘└───────────────┘└┘ ┴ ┴ └─
typ ────┘└───────────────┘└┘ └──────────────┘┴└┘┴└┘└─
doc ────┘ └┘ ┴ ┴ └─
txt ────┘ └┘ ┴ ┴ └─
par ────┘ └┘ ┴ ┴ └─
pid ────┘ └┘ ┴ ┴ ┴└
st ─────────────────────────────────────────────────
5040
src ─
typ ─
doc ─
txt ─
par ─
pid ─
st ─
5041 /- add -/
src ──────────
typ ──────────
doc ──────────
txt ──────────
par ──────────
pid ──────────
st ──────────
5042
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
5043 @[simp] lemma get_add {α : Type u} [add_monoid α] {k : ℕ} {xs ys : list α} :
id └────────┘ ┴ ┴ └──┘ ┴
src └────────┘ ┴ └──┘
typ └────────┘ ┴ ┴ └──┘ ┴
doc └──┘
5044 @get α ⟨0⟩ k (add xs ys) = ( @get α ⟨0⟩ k xs + @get α ⟨0⟩ k ys) :=
id └─┘ ┴ ┴ └─┘ └┘ └┘ ┴ └─┘ ┴ ┴ └┘ ┴ └─┘ ┴ ┴ └┘
src └─┘ └─┘ ┴ └─┘ ┴ └─┘
typ └─┘ ┴ ┴ └─┘ └┘ └┘ ┴ └─┘ ┴ ┴ └┘ ┴ └─┘ ┴ ┴ └┘
5045 by {apply get_pointwise, apply zero_add}
id └───────────┘ └──────┘
src └────┘└───────────┘ └────┘└──────┘
typ └────┘└───────────┘ └────┘└──────┘
doc └────┘ └────┘
txt └────┘ └────┘
par └────┘ └────┘
pid ┴ ┴
st └───────────────────┘└──────────────┘└┘
5046
5047 @[simp] lemma length_add {α : Type u}
doc └──┘
5048 [has_zero α] [has_add α] {xs ys : list α} :
id └──────┘ ┴ └─────┘ ┴ └──┘ ┴
src └──────┘ └─────┘ └──┘
typ └──────┘ ┴ └─────┘ ┴ └──┘ ┴
5049 (add xs ys).length = _root_.max xs.length ys.length :=
id └─┘ └┘ └┘ └────┘ ┴ └────────┘ └┘└─────┘ └┘└─────┘
src └─┘ └────┘ ┴ └────────┘ └─────┘ └─────┘
typ └─┘ └┘ └┘ └────┘ ┴ └────────┘ └┘└─────┘ └┘└─────┘
5050 @length_pointwise α α α ⟨0⟩ ⟨0⟩ _ _ _
id └──────────────┘ ┴ ┴ ┴
src └──────────────┘
typ └──────────────┘ ┴ ┴ ┴
5051
5052 @[simp] lemma nil_add {α : Type u} [add_monoid α]
id └────────┘ ┴
src └────────┘
typ └────────┘ ┴
doc └──┘
5053 (as : list α) : add [] as = as :=
id └──┘ ┴ └─┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ └┘ ┴
typ └──┘ ┴ └─┘ └┘ └┘ ┴ └┘
5054 begin
st └─────
5055 rw [add, @nil_pointwise α α α ⟨0⟩ ⟨0⟩],
id └─┘ └───────────┘ ┴
src └──┘└─┘└┘ └───────────┘┴ ┴ ┴ ┴ └─┘ └─┘
typ └──┘└─┘└┘ └───────────┘┴ ┴ ┴┴┴ └─┘ └─┘
doc └──┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
txt └──┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
par └──┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
pid └┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
st ────────┘└────────────────────────────┘└──
5056 apply eq.trans _ (map_id as),
id └──────┘ └────┘ └┘
src └────┘└──────┘└─┘ └────┘┴ ┴
typ └────┘└──────┘└─┘ └────┘┴└┘┴
doc └────┘ └─┘ ┴ ┴
txt └────┘ └─┘ ┴ ┴
par └────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ─────────────────────────────┘└─
5057 congr, ext,
src └───┘ └─┘
typ └───┘ └─┘
doc └─┘
txt └───┘ └─┘
par └───┘ └─┘
st ──────┘└───┘└─
5058 have : @default α ⟨0⟩ = 0 := rfl,
id └─────┘ ┴ ┴ └─┘
src └─────┘ └─────┘┴ ┴ └─┘┴└────┘└─┘
typ └─────┘ └─────┘┴┴┴ └─┘┴└────┘└─┘
doc └─────┘ ┴ ┴ └─┘ └────┘
txt └─────┘ ┴ ┴ └─┘ └────┘
par └─────┘ ┴ ┴ └─┘ └────┘
pid └───┘└┘ ┴ ┴ └─┘ ┴└───┘
st ─────────────────────────────────┘└─
5059 rw [this, zero_add], refl
id └──┘ └──────┘
src └──┘ └┘└──────┘┴ └───┘
typ └──┘└──┘└┘└──────┘┴ └───┘
doc └──┘ └┘ ┴ └───┘
txt └──┘ └┘ ┴ └───┘
par └──┘ └┘ ┴ └───┘
pid └┘ └┘ ┴ ┴
st ─────────┘└────────┘└──────┘
5060 end
st └─┘
5061
5062 @[simp] lemma add_nil {α : Type u} [add_monoid α]
id └────────┘ ┴
src └────────┘
typ └────────┘ ┴
doc └──┘
5063 (as : list α) : add as [] = as :=
id └──┘ ┴ └─┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ └┘ ┴
typ └──┘ ┴ └─┘ └┘ └┘ ┴ └┘
5064 begin
st └─────
5065 rw [add, @pointwise_nil α α α ⟨0⟩ ⟨0⟩],
id └─┘ └───────────┘ ┴
src └──┘└─┘└┘ └───────────┘┴ ┴ ┴ ┴ └─┘ └─┘
typ └──┘└─┘└┘ └───────────┘┴ ┴ ┴┴┴ └─┘ └─┘
doc └──┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
txt └──┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
par └──┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
pid └┘ └┘ ┴ ┴ ┴ ┴ └─┘ └─┘
st ────────┘└────────────────────────────┘└──
5066 apply eq.trans _ (map_id as),
id └──────┘ └────┘ └┘
src └────┘└──────┘└─┘ └────┘┴ ┴
typ └────┘└──────┘└─┘ └────┘┴└┘┴
doc └────┘ └─┘ ┴ ┴
txt └────┘ └─┘ ┴ ┴
par └────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ─────────────────────────────┘└─
5067 congr, ext,
src └───┘ └─┘
typ └───┘ └─┘
doc └─┘
txt └───┘ └─┘
par └───┘ └─┘
st ──────┘└───┘└─
5068 have : @default α ⟨0⟩ = 0 := rfl,
id └─────┘ ┴ ┴ └─┘
src └─────┘ └─────┘┴ ┴ └─┘┴└────┘└─┘
typ └─────┘ └─────┘┴┴┴ └─┘┴└────┘└─┘
doc └─────┘ ┴ ┴ └─┘ └────┘
txt └─────┘ ┴ ┴ └─┘ └────┘
par └─────┘ ┴ ┴ └─┘ └────┘
pid └───┘└┘ ┴ ┴ └─┘ ┴└───┘
st ─────────────────────────────────┘└─
5069 rw [this, add_zero], refl
id └──┘ └──────┘
src └──┘ └┘└──────┘┴ └───┘
typ └──┘└──┘└┘└──────┘┴ └───┘
doc └──┘ └┘ ┴ └───┘
txt └──┘ └┘ ┴ └───┘
par └──┘ └┘ ┴ └───┘
pid └┘ └┘ ┴ ┴
st ─────────┘└────────┘└──────┘
5070 end
st └─┘
5071
5072 lemma map_add_map {α : Type u} [add_monoid α] (f g : α → α) {as : list α} :
id └────────┘ ┴ ┴ ┴ └──┘ ┴
src └────────┘ └──┘
typ └────────┘ ┴ ┴ ┴ └──┘ ┴
5073 add (as.map f) (as.map g) = as.map (λ x, f x + g x) :=
id └─┘ └┘└──┘ ┴ └┘└──┘ ┴ ┴ └┘└──┘ ┴ ┴ ┴ ┴ ┴ ┴
src └─┘ └──┘ └──┘ ┴ └──┘ ┴
typ └─┘ └┘└──┘ ┴ └┘└──┘ ┴ ┴ └┘└──┘ ┴ ┴ ┴ ┴ ┴ ┴
5074 begin
st └─────
5075 apply @eq_of_equiv _ (⟨0⟩ : inhabited α),
id └─────────┘ └───────┘ ┴
src └────┘ └─────────┘└─┘ └───┘└───────┘┴ ┴
typ └────┘ └─────────┘└─┘ └───┘└───────┘┴┴┴
doc └────┘ └─┘ └───┘ ┴ ┴
txt └────┘ └─┘ └───┘ ┴ ┴
par └────┘ └─┘ └───┘ ┴ ┴
pid ┴ └─┘ └───┘ ┴ ┴
st ─────────────────────────────────────────┘└─
5076 { rw [length_map, length_add, max_eq_left, length_map],
id └────────┘ └────────┘ └─────────┘ └────────┘
src └──┘└────────┘└┘└────────┘└┘└─────────┘└┘└────────┘┴
typ └──┘└────────┘└┘└────────┘└┘└─────────┘└┘└────────┘┴
doc └──┘ └┘ └┘ └┘ ┴
txt └──┘ └┘ └┘ └┘ ┴
par └──┘ └┘ └┘ └┘ ┴
pid └┘ └┘ └┘ └┘ ┴
st ───┘└────────────┘└──────────┘└───────────┘└──────────┘└──
5077 apply le_of_eq,
id └──────┘
src └────┘└──────┘
typ └────┘└──────┘
doc └────┘
txt └────┘
par └────┘
pid ┴
st ─────────────────┘└─
5078 rw [length_map, length_map] },
id └────────┘ └────────┘
src └──┘└────────┘└┘└────────┘└┘
typ └──┘└────────┘└┘└────────┘└┘
doc └──┘ └┘ └┘
txt └──┘ └┘ └┘
par └──┘ └┘ └┘
pid └┘ └┘ ┴┴
st ─────────────────┘└──────────┘┴┴└┘└
5079 intros m,
src └──────┘
typ └──────┘
doc └──────┘
txt └──────┘
par └──────┘
pid └┘
st ─────────┘└─
5080 rw [get_add],
id └─────┘
src └──┘└─────┘┴
typ └──┘└─────┘┴
doc └──┘ ┴
txt └──┘ ┴
par └──┘ ┴
pid └┘ ┴
st ────────────┘└──
5081 by_cases h : m < length as,
id ┴ ┴ └────┘ └┘
src └───────┘ └─┘ ┴┴┴└────┘┴
typ └───────┘ └─┘┴┴┴┴└────┘┴└┘
doc └───────┘ └─┘ ┴ ┴ ┴
txt └───────┘ └─┘ ┴ ┴ ┴
par └───────┘ └─┘ ┴ ┴ ┴
pid ┴ └─┘ ┴ ┴ ┴
st ───────────────────────────┘└─
5082 { repeat {rw [@get_map α α ⟨0⟩ ⟨0⟩ _ _ _ h]} },
id └─────┘ ┴ ┴
src └──────┘└──┘ └─────┘┴ ┴ ┴ └─┘ └───────┘ ┴└┘
typ └──────┘└──┘ └─────┘┴ ┴┴┴ └─┘ └───────┘┴┴└┘
doc └──────┘└──┘ ┴ ┴ ┴ └─┘ └───────┘ ┴└┘
txt └──────┘└──┘ ┴ ┴ ┴ └─┘ └───────┘ ┴└┘
par └──────┘└──┘ ┴ ┴ ┴ └─┘ └───────┘ ┴└┘
pid └────┘ ┴ ┴ ┴ └─┘ └───────┘ └┘┴
st ───┘└──────────────────────────────────────┘└┘┴└┘└
5083 rw not_lt at h,
id └────┘
src └─┘└────┘└───┘
typ └─┘└────┘└───┘
doc └─┘ └───┘
txt └─┘ └───┘
par └─┘ └───┘
pid ┴ └───┘
st ───────────────┘└─
5084 repeat {rw [get_eq_default_of_le m]};
id └──────────────────┘ ┴
src └──────┘└──┘└──────────────────┘┴ ┴┴
typ └──────┘└──┘└──────────────────┘┴┴┴┴
doc └──────┘└──┘ ┴ ┴┴
txt └──────┘└──┘ ┴ ┴┴
par └──────┘└──┘ ┴ ┴┴
pid └────┘ ┴ └┘
st ───────────────────────────────────┘└─┘└
5085 try {rw length_map, apply h},
id └────────┘
src └───┘└─┘└────────┘└┘└────┘ ┴
typ └───┘└─┘└────────┘└┘└────┘ ┴
doc └───┘└─┘ └┘└────┘ ┴
txt └───┘└─┘ └┘└────┘ ┴
par └───┘└─┘ └┘└────┘ ┴
pid └───┘ └──────┘ ┴
st ──────┘└───────────┘└───────┘└┘└
5086 apply zero_add
id └──────┘
src └────┘└──────┘┴
typ └────┘└──────┘┴
doc └────┘ ┴
txt └────┘ ┴
par └────┘ ┴
pid ┴ ┴
st ────────────────┘
5087 end
st └─┘
5088
5089 /- sub -/
5090
5091 @[simp] lemma get_sub {α : Type u}
doc └──┘
5092 [add_group α] {k : ℕ} {xs ys : list α} :
id └───────┘ ┴ ┴ └──┘ ┴
src └───────┘ ┴ └──┘
typ └───────┘ ┴ ┴ └──┘ ┴
5093 @get α ⟨0⟩ k (sub xs ys) = (@get α ⟨0⟩ k xs - @get α ⟨0⟩ k ys) :=
id └─┘ ┴ ┴ └─┘ └┘ └┘ ┴ └─┘ ┴ ┴ └┘ ┴ └─┘ ┴ ┴ └┘
src └─┘ └─┘ ┴ └─┘ ┴ └─┘
typ └─┘ ┴ ┴ └─┘ └┘ └┘ ┴ └─┘ ┴ ┴ └┘ ┴ └─┘ ┴ ┴ └┘
5094 by {apply get_pointwise, apply sub_zero}
id └───────────┘ └──────┘
src └────┘└───────────┘ └────┘└──────┘
typ └────┘└───────────┘ └────┘└──────┘
doc └────┘ └────┘
txt └────┘ └────┘
par └────┘ └────┘
pid ┴ ┴
st └───────────────────┘└──────────────┘└┘
5095
5096 @[simp] lemma length_sub [has_zero α] [has_sub α] {xs ys : list α} :
id └──────┘ ┴ └─────┘ ┴ └──┘ ┴
src └──────┘ └─────┘ └──┘
typ └──────┘ ┴ └─────┘ ┴ └──┘ ┴
doc └──┘
5097 (sub xs ys).length = _root_.max xs.length ys.length :=
id └─┘ └┘ └┘ └────┘ ┴ └────────┘ └┘└─────┘ └┘└─────┘
src └─┘ └────┘ ┴ └────────┘ └─────┘ └─────┘
typ └─┘ └┘ └┘ └────┘ ┴ └────────┘ └┘└─────┘ └┘└─────┘
5098 @length_pointwise α α α ⟨0⟩ ⟨0⟩ _ _ _
id └──────────────┘ ┴ ┴ ┴
src └──────────────┘
typ └──────────────┘ ┴ ┴ ┴
5099
5100 @[simp] lemma nil_sub {α : Type} [add_group α]
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
doc └──┘
5101 (as : list α) : sub [] as = neg as :=
id └──┘ ┴ └─┘ └┘ └┘ ┴ └─┘ └┘
src └──┘ └─┘ └┘ ┴ └─┘
typ └──┘ ┴ └─┘ └┘ └┘ ┴ └─┘ └┘
5102 begin
st └─────
5103 rw [sub, nil_pointwise],
id └─┘ └───────────┘
src └──┘└─┘└┘└───────────┘┴
typ └──┘└─┘└┘└───────────┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ────────┘└─────────────┘└──
5104 congr, ext,
src └───┘ └─┘
typ └───┘ └─┘
doc └─┘
txt └───┘ └─┘
par └───┘ └─┘
st ──────┘└───┘└─
5105 have : @default α ⟨0⟩ = 0 := rfl,
id └─────┘ ┴ ┴ └─┘
src └─────┘ └─────┘┴ ┴ └─┘┴└────┘└─┘
typ └─────┘ └─────┘┴┴┴ └─┘┴└────┘└─┘
doc └─────┘ ┴ ┴ └─┘ └────┘
txt └─────┘ ┴ ┴ └─┘ └────┘
par └─────┘ ┴ ┴ └─┘ └────┘
pid └───┘└┘ ┴ ┴ └─┘ ┴└───┘
st ─────────────────────────────────┘└─
5106 rw [this, zero_sub]
id └──┘ └──────┘
src └──┘ └┘└──────┘└┘
typ └──┘└──┘└┘└──────┘└┘
doc └──┘ └┘ └┘
txt └──┘ └┘ └┘
par └──┘ └┘ └┘
pid └┘ └┘ ┴┴
st ─────────┘└────────┘┴┴
5107 end
st └─┘
5108
5109 @[simp] lemma sub_nil {α : Type} [add_group α]
id └───────┘ ┴
src └───────┘
typ └───────┘ ┴
doc └──┘
5110 (as : list α) : sub as [] = as :=
id └──┘ ┴ └─┘ └┘ └┘ ┴ └┘
src └──┘ └─┘ └┘ ┴
typ └──┘ ┴ └─┘ └┘ └┘ ┴ └┘
5111 begin
st └─────
5112 rw [sub, pointwise_nil],
id └─┘ └───────────┘
src └──┘└─┘└┘└───────────┘┴
typ └──┘└─┘└┘└───────────┘┴
doc └──┘ └┘ ┴
txt └──┘ └┘ ┴
par └──┘ └┘ ┴
pid └┘ └┘ ┴
st ────────┘└─────────────┘└──
5113 apply eq.trans _ (map_id as),
id └──────┘ └────┘ └┘
src └────┘└──────┘└─┘ └────┘┴ ┴
typ └────┘└──────┘└─┘ └────┘┴└┘┴
doc └────┘ └─┘ ┴ ┴
txt └────┘ └─┘ ┴ ┴
par └────┘ └─┘ ┴ ┴
pid ┴ └─┘ ┴ ┴
st ─────────────────────────────┘└─
5114 congr, ext,
src └───┘ └─┘
typ └───┘ └─┘
doc └─┘
txt └───┘ └─┘
par └───┘ └─┘
st ──────┘└───┘└─
5115 have : @default α ⟨0⟩ = 0 := rfl,
id └─────┘ ┴ ┴ └─┘
src └─────┘ └─────┘┴ ┴ └─┘┴└────┘└─┘
typ └─────┘ └─────┘┴┴┴ └─┘┴└────┘└─┘
doc └─────┘ ┴ ┴ └─┘ └────┘
txt └─────┘ ┴ ┴ └─┘ └────┘
par └─────┘ ┴ ┴ └─┘ └────┘
pid └───┘└┘ ┴ ┴ └─┘ ┴└───┘
st ─────────────────────────────────┘└─
5116 rw [this, sub_zero], refl
id └──┘ └──────┘
src └──┘ └┘└──────┘┴ └───┘
typ └──┘└──┘└┘└──────┘┴ └───┘
doc └──┘ └┘ ┴ └───┘
txt └──┘ └┘ ┴ └───┘
par └──┘ └┘ ┴ └───┘
pid └┘ └┘ ┴ ┴
st ─────────┘└────────┘└──────┘
5117 end
st └─┘
5118
5119 end func
5120
5121 namespace nat
5122
5123 /-- The antidiagonal of a natural number `n` is the list of pairs `(i,j)` such that `i+j = n`. -/
5124 def antidiagonal (n : ℕ) : list (ℕ × ℕ) :=
id ┴ └──┘ ┴ ┴ ┴
src ┴ └──┘ ┴ ┴ ┴
typ ┴ └──┘ ┴ ┴ ┴
5125 (range (n+1)).map (λ i, (i, n - i))
id └───┘ ┴┴ └─┘ ┴ ┴┴ ┴ ┴ ┴
src └───┘ ┴ └─┘ ┴ ┴
typ └───┘ ┴┴ └─┘ ┴ ┴┴ ┴ ┴ ┴
5126
5127 /-- A pair (i,j) is contained in the antidiagonal of `n` if and only if `i+j=n`. -/
5128 @[simp] lemma mem_antidiagonal {n : ℕ} {x : ℕ × ℕ} :
id ┴ ┴ ┴ ┴
src ┴ ┴ ┴ ┴
typ ┴ ┴ ┴ ┴
doc └──┘
5129 x ∈ antidiagonal n ↔ x.1 + x.2 = n :=
id ┴ ┴ └──────────┘ ┴ ┴ ┴┴ ┴ ┴┴ ┴ ┴
src ┴ └──────────┘ ┴ ┴ ┴ ┴ ┴
typ ┴ ┴ └──────────┘ ┴ ┴ ┴┴ ┴ ┴┴ ┴ ┴
doc └──────────┘
5130 begin
st └─────
5131 rw [antidiagonal, mem_map], split,
id └──────────┘ └─────┘
src └──┘└──────────┘└┘└─────┘┴ └───┘
typ └──┘└──────────┘└┘└─────┘┴ └───┘
doc └──┘└──────────┘└┘ ┴ └───┘
txt └──┘ └┘ ┴ └───┘
par └──┘ └┘ ┴ └───┘
pid └┘ └┘ ┴
st ─────────────────┘└───────┘└──────┘└─
5132 { rintros ⟨i, hi, rfl⟩, rw [mem_range, lt_succ_iff] at hi, exact add_sub_of_le hi },
id └───────┘ └─────────┘ └───────────┘ └┘
src └──────────────────┘ └──┘└───────┘└┘└─────────┘└─────┘ └────┘└───────────┘┴ ┴
typ └──────────────────┘ └──┘└───────┘└┘└─────────┘└─────┘ └────┘└───────────┘┴└┘┴
doc └──────────────────┘ └──┘ └┘ └─────┘ └────┘ ┴ ┴
txt └──────────────────┘ └──┘ └┘ └─────┘ └────┘ ┴ ┴
par └──────────────────┘ └──┘ └┘ └─────┘ └────┘ ┴ ┴
pid └───────────┘ └┘ └┘ ┴└────┘ ┴ ┴ ┴
st ───┘└──────────────────┘└─────────────┘└───────────┘┴└────┘└───────────────────────┘└┘└
5133 { rintro rfl, refine ⟨x.fst, _, _⟩,
id └───┘
src └────────┘ └─────┘ └───┘└─────┘
typ └────────┘ └─────┘ └───┘└─────┘
doc └────────┘ └─────┘ └─────┘
txt └────────┘ └─────┘ └─────┘
par └────────┘ └─────┘ └─────┘
pid └──┘ ┴ └─────┘
st ─────────────┘└────────────────────┘└─
5134 { rw [mem_range, add_assoc, lt_add_iff_pos_right], exact zero_lt_succ _ },
id └───────┘ └───────┘ └──────────────────┘ └──────────┘
src └──┘└───────┘└┘└───────┘└┘└──────────────────┘┴ └────┘└──────────┘└─┘
typ └──┘└───────┘└┘└───────┘└┘└──────────────────┘┴ └────┘└──────────┘└─┘
doc └──┘ └┘ └┘ ┴ └────┘ └─┘
txt └──┘ └┘ └┘ ┴ └────┘ └─┘
par └──┘ └┘ └┘ ┴ └────┘ └─┘
pid └┘ └┘ └┘ ┴ ┴ └┘┴
st ─────┘└───────────┘└─────────┘└────────────────────┘└──────────────────────┘└┘└
5135 { exact prod.ext rfl (nat.add_sub_cancel_left _ _) } }
id └──────┘ └─┘ └─────────────────────┘
src └────┘└──────┘┴└─┘┴ └─────────────────────┘└────┘
typ └────┘└──────┘┴└─┘┴ └─────────────────────┘└────┘
doc └────┘ ┴ ┴ └────┘
txt └────┘ ┴ ┴ └────┘
par └────┘ ┴ ┴ └────┘
pid ┴ ┴ ┴ └───┘┴
st ──────────────────────────────────────────────────────┘└───
5136 end
st ──┘
5137
5138 /-- The length of the antidiagonal of `n` is `n+1`. -/
5139 @[simp] lemma length_antidiagonal (n : ℕ) : (antidiagonal n).length = n+1 :=
id ┴ └──────────┘ ┴ └────┘ ┴ ┴┴
src ┴ └──────────┘ └────┘ ┴ ┴
typ ┴ └──────────┘ ┴ └────┘ ┴ ┴┴
doc └──┘ └──────────┘
5140 by rw [antidiagonal, length_map, length_range]
id └──────────┘ └────────┘ └──────────┘
src └──┘└──────────┘└┘└────────┘└┘└──────────┘└─
typ └──┘└──────────┘└┘└────────┘└┘└──────────┘└─
doc └──┘└──────────┘└┘ └┘ └─
txt └──┘ └┘ └┘ └─
par └──┘ └┘ └┘ └─
pid └┘ └┘ └┘ ┴└
st └───────────────┘└──────────┘└────────────┘┴└
5141
src ┘
typ ┘
doc ┘
txt ┘
par ┘
pid ┘
st ┘
5142 /-- The antidiagonal of `0` is the list `[(0,0)]` -/
5143 @[simp] lemma antidiagonal_zero : antidiagonal 0 = [(0, 0)] :=
id └──────────┘ ┴ ┴┴ ┴
src └──────────┘ ┴ ┴┴ ┴
typ └──────────┘ ┴ ┴┴ ┴
doc └──┘ └──────────┘
5144 ext_le (length_antidiagonal 0) $ λ n h₁ h₂,
id └────┘ └─────────────────┘ ┴ └┘ └┘
src └────┘ └─────────────────┘
typ └────┘ └─────────────────┘ ┴ └┘ └┘
doc └─────────────────┘
5145 begin
st └─────
5146 rw [length_antidiagonal, lt_succ_iff, le_zero_iff] at h₁,
id └─────────────────┘ └─────────┘ └─────────┘
src └──┘└─────────────────┘└┘└─────────┘└┘└─────────┘└─────┘
typ └──┘└─────────────────┘└┘└─────────┘└┘└─────────┘└─────┘
doc └──┘└─────────────────┘└┘ └┘ └─────┘
txt └──┘ └┘ └┘ └─────┘
par └──┘ └┘ └┘ └─────┘
pid └┘ └┘ └┘ ┴└────┘
st ────────────────────────┘└───────────┘└───────────┘┴└────┘└─
5147 subst n, simp [antidiagonal]
id ┴ └──────────┘
src └────┘ └────┘└──────────┘└┘
typ └────┘┴ └────┘└──────────┘└┘
doc └────┘ └────┘└──────────┘└┘
txt └────┘ └────┘ └┘
par └────┘ └────┘ └┘
pid ┴ ┴┴ ┴┴
st ────────┘└────────────────────┘
5148 end
st └─┘
5149
5150 /-- The antidiagonal of `n` does not contain duplicate entries. -/
5151 lemma nodup_antidiagonal (n : ℕ) : nodup (antidiagonal n) :=
id ┴ └───┘ └──────────┘ ┴
src ┴ └───┘ └──────────┘
typ ┴ └───┘ └──────────┘ ┴
doc └───┘ └──────────┘
5152 nodup_map (@injective_of_left_inverse ℕ (ℕ × ℕ) prod.fst (λ i, (i, n-i)) $ λ i, rfl) (nodup_range _)
id └───────┘ └───────────────────────┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴┴ ┴┴┴ ┴ └─┘ └─────────┘
src └───────┘ └───────────────────────┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴ └─┘ └─────────┘
typ └───────┘ └───────────────────────┘ ┴ ┴ ┴ ┴ └──────┘ ┴ ┴┴ ┴┴┴ ┴ └─┘ └─────────┘
5153
5154 end nat
5155
5156 end list
5157
5158 theorem option.to_list_nodup {α} : ∀ o : option α, o.to_list.nodup
id ┴ └────┘ ┴ ┴└──────┘└────┘
src └────┘ └──────┘└────┘
typ ┴ └────┘ ┴ ┴└──────┘└────┘
doc └────┘
5159 | none := list.nodup_nil
id └──┘ └────────────┘
src └──┘ └────────────┘
typ └──┘ └────────────┘
5160 | (some x) := list.nodup_singleton x
id └──┘ ┴ └──────────────────┘
src └──┘ └──────────────────┘
typ └──┘ ┴ └──────────────────┘
5161
5162 @[to_additive]
doc └─────────┘
5163 theorem monoid_hom.map_list_prod {α β : Type*} [monoid α] [monoid β] (f : α →* β) (l : list α) :
id └────┘ ┴ └────┘ ┴ ┴ └┘ ┴ └──┘ ┴
src └────┘ └────┘ └┘ └──┘
typ └────┘ ┴ └────┘ ┴ ┴ └┘ ┴ └──┘ ┴
doc └┘
5164 f l.prod = (l.map f).prod :=
id ┴ ┴└───┘ ┴ ┴└──┘ ┴ └──┘
src └───┘ ┴ └──┘ └──┘
typ ┴ ┴└───┘ ┴ ┴└──┘ ┴ └──┘
doc └───┘ └──┘
5165 (l.prod_hom f).symm
id ┴└───────┘ ┴ └──┘
src └───────┘ └──┘
typ ┴└───────┘ ┴ └──┘